]> sourceware.org Git - systemtap.git/blame - tapsets.cxx
none
[systemtap.git] / tapsets.cxx
CommitLineData
56e12059
FCE
1// tapset resolution
2// Copyright (C) 2005 Red Hat Inc.
3//
4// This file is part of systemtap, and is free software. You can
5// redistribute it and/or modify it under the terms of the GNU General
6// Public License (GPL); either version 2, or (at your option) any
7// later version.
8
9#include "config.h"
10#include "staptree.h"
11#include "elaborate.h"
b55bc428 12#include "tapsets.h"
56e12059 13#include "translate.h"
bd2b1e68
GH
14
15#include <deque>
56e12059 16#include <iostream>
bd2b1e68 17#include <map>
ec4373ff 18#include <set>
56e12059 19#include <sstream>
bd2b1e68 20#include <stdexcept>
b55bc428 21#include <vector>
e36387d7 22#include <cstdarg>
bd2b1e68
GH
23
24extern "C" {
df8fadee 25#include <fcntl.h>
bd2b1e68 26#include <elfutils/libdwfl.h>
7a053d3b 27#include <elfutils/libdw.h>
77de5e9e
GH
28#include <dwarf.h>
29#include <elf.h>
30#include <obstack.h>
31#include "loc2c.h"
4b1ad75e
RM
32
33#define __STDC_FORMAT_MACROS
34#include <inttypes.h>
bd2b1e68 35}
77de5e9e 36
bd2b1e68 37#include <fnmatch.h>
56e12059
FCE
38
39using namespace std;
40
cc9ee605
FCE
41
42// XXX: should standardize to these functions throughout translator
43
44template <typename OUT, typename IN> inline OUT
45lex_cast(IN const & in)
46{
47 stringstream ss;
48 OUT out;
49 if (!(ss << in && ss >> out))
50 throw runtime_error("bad lexical cast");
51 return out;
52}
53
54template <typename OUT, typename IN> inline OUT
55lex_cast_hex(IN const & in)
56{
57 stringstream ss;
58 OUT out;
59 if (!(ss << hex << showbase << in && ss >> out))
60 throw runtime_error("bad lexical cast");
61 return out;
62}
63
64
65// return as quoted string, with at least '"' backslash-escaped
66template <typename IN> inline string
67lex_cast_qstring(IN const & in)
68{
69 stringstream ss;
70 string out, out2;
499cf740 71 if (!(ss << in))
cc9ee605 72 throw runtime_error("bad lexical cast");
499cf740 73 out = ss.str();
cc9ee605
FCE
74 out2 += '"';
75 for (unsigned i=0; i<out.length(); i++)
76 {
77 if (out[i] == '"') // XXX others?
78 out2 += '\\';
79 out2 += out[i];
80 }
81 out2 += '"';
82 return out2;
83}
84
85
b55bc428
FCE
86// ------------------------------------------------------------------------
87// begin/end probes are run right during registration / deregistration
56e12059
FCE
88// ------------------------------------------------------------------------
89
b55bc428
FCE
90struct be_derived_probe: public derived_probe
91{
92 bool begin;
93 be_derived_probe (probe* p, bool b): derived_probe (p), begin (b) {}
94 be_derived_probe (probe* p, probe_point* l, bool b):
95 derived_probe (p, l), begin (b) {}
56e12059 96
b55bc428
FCE
97 void emit_registrations (translator_output* o, unsigned i);
98 void emit_deregistrations (translator_output* o, unsigned i);
99 void emit_probe_entries (translator_output* o, unsigned i);
100};
101
98afd80e
FCE
102
103struct be_builder: public derived_probe_builder
b55bc428
FCE
104{
105 bool begin;
106 be_builder(bool b) : begin(b) {}
5227f1ea 107 virtual void build(systemtap_session & sess,
7a053d3b 108 probe * base,
20c6c071
GH
109 probe_point * location,
110 std::map<std::string, literal *> const & parameters,
111 vector<probe *> & results_to_expand_further,
112 vector<derived_probe *> & finished_results)
b55bc428 113 {
20c6c071 114 finished_results.push_back(new be_derived_probe(base, location, begin));
b55bc428 115 }
b55bc428 116};
56e12059
FCE
117
118
7a053d3b 119void
56e12059
FCE
120be_derived_probe::emit_registrations (translator_output* o, unsigned j)
121{
122 if (begin)
123 for (unsigned i=0; i<locations.size(); i++)
bfb3d2d2 124 o->newline() << "enter_" << j << "_" << i << " ();";
56e12059
FCE
125}
126
127
7a053d3b 128void
56e12059
FCE
129be_derived_probe::emit_deregistrations (translator_output* o, unsigned j)
130{
bfb3d2d2 131 if (!begin)
56e12059 132 for (unsigned i=0; i<locations.size(); i++)
bfb3d2d2 133 o->newline() << "enter_" << j << "_" << i << " ();";
56e12059
FCE
134}
135
136
137void
138be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
139{
140 for (unsigned i=0; i<locations.size(); i++)
141 {
142 probe_point *l = locations[i];
143 o->newline() << "/* location " << i << ": " << *l << " */";
f4b28491
FCE
144 o->newline() << "static void enter_" << j << "_" << i << " (void);";
145 o->newline() << "void enter_" << j << "_" << i << " () {";
bfb3d2d2 146
7a053d3b 147 // While begin/end probes are executed single-threaded, we
bfb3d2d2
FCE
148 // still code defensively and use a per-cpu context.
149 o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
cc9ee605
FCE
150 o->newline() << "const char* probe_point = "
151 << lex_cast_qstring(*l) << ";";
bfb3d2d2
FCE
152
153 // A precondition for running a probe handler is that we're in STARTING
154 // or STOPPING state (not ERROR), and that no one else is already using
155 // this context.
156 o->newline() << "if (atomic_read (&session_state) != ";
157 if (begin) o->line() << "STAP_SESSION_STARTING)";
158 else o->line() << "STAP_SESSION_STOPPING)";
159 o->newline(1) << "return;";
cc9ee605 160 o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
499cf740 161 o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
cc9ee605 162 << "c->probe_point, probe_point);";
bfb3d2d2
FCE
163 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
164 o->newline() << "return;";
165 o->newline(-1) << "}";
166 o->newline();
5e309481 167 o->newline() << "c->last_error = 0;";
cc9ee605 168 o->newline() << "c->probe_point = probe_point;";
56e12059 169 o->newline() << "c->nesting = 0;";
3d49c615 170 o->newline() << "c->regs = 0;";
5e309481 171 o->newline() << "c->actioncount = 0;";
bfb3d2d2 172
56e12059
FCE
173 // NB: locals are initialized by probe function itself
174 o->newline() << "probe_" << j << " (c);";
bfb3d2d2 175
bb788f9f
FCE
176 o->newline() << "if (c->last_error && c->last_error[0]) {";
177 o->newline(1) << "_stp_error (\"%s near %s\", c->last_error, c->last_stmt);";
5e309481 178 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
bfb3d2d2
FCE
179 o->newline(-1) << "}";
180
cc9ee605 181 o->newline() << "atomic_dec (&c->busy);";
56e12059
FCE
182 o->newline(-1) << "}" << endl;
183 }
184}
185
186
187// ------------------------------------------------------------------------
bd2b1e68 188// Dwarf derived probes.
b55bc428 189// ------------------------------------------------------------------------
bd2b1e68 190
c239d28c
GH
191static string TOK_PROCESS("process");
192static string TOK_KERNEL("kernel");
193static string TOK_MODULE("module");
194
195static string TOK_FUNCTION("function");
196static string TOK_RETURN("return");
197static string TOK_CALLEES("callees");
198
199static string TOK_STATEMENT("statement");
200static string TOK_LABEL("label");
201static string TOK_RELATIVE("relative");
202
59ff2773 203
59ff2773 204
59ff2773 205
7e1279ea
FCE
206struct
207func_info
208{
209 string name;
4cd232e4
GH
210 char const * decl_file;
211 int decl_line;
7e1279ea
FCE
212 Dwarf_Die die;
213 Dwarf_Addr prologue_end;
214};
215
216struct
217inline_instance_info
218{
219 string name;
4cd232e4
GH
220 char const * decl_file;
221 int decl_line;
7e1279ea
FCE
222 Dwarf_Die die;
223};
224
225static int
226query_cu (Dwarf_Die * cudie, void * arg);
59ff2773
FCE
227
228
bd2b1e68
GH
229// Helper for dealing with selected portions of libdwfl in a more readable
230// fashion, and with specific cleanup / checking / logging options.
231
91eefb1c
GH
232static const char *
233dwarf_diename_integrate (Dwarf_Die *die)
234{
235 Dwarf_Attribute attr_mem;
236 return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
237}
238
bd2b1e68
GH
239struct
240dwflpp
241{
5227f1ea 242 systemtap_session & sess;
bd2b1e68
GH
243 Dwfl * dwfl;
244
245 // These are "current" values we focus on.
246 Dwfl_Module * module;
247 Dwarf * module_dwarf;
248 Dwarf_Addr module_bias;
50e0d793
GH
249
250 // These describe the current module's PC address range
251 Dwarf_Addr module_start;
252 Dwarf_Addr module_end;
253
bd2b1e68
GH
254 Dwarf_Die * cu;
255 Dwarf_Func * function;
256
257 string module_name;
258 string cu_name;
259 string function_name;
260
50e0d793 261
7a053d3b 262 string const default_name(char const * in,
bd2b1e68
GH
263 char const * type)
264 {
7a053d3b 265 if (in)
bd2b1e68 266 return in;
24cb178f 267 if (false && sess.verbose)
bd2b1e68 268 clog << "WARNING: no name found for " << type << endl;
a229fcd7 269 return string("");
bd2b1e68
GH
270 }
271
50e0d793 272
5227f1ea
GH
273 void get_module_dwarf()
274 {
275 if (!module_dwarf)
276 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
7e1279ea 277
a229fcd7 278 if (module_dwarf == NULL && sess.verbose)
d9b516ca 279 clog << "WARNING: dwfl_module_getdwarf() : "
a229fcd7 280 << dwfl_errmsg (dwfl_errno ()) << endl;
5227f1ea
GH
281 }
282
50e0d793 283
bd2b1e68
GH
284 void focus_on_module(Dwfl_Module * m)
285 {
286 assert(m);
287 module = m;
7a053d3b 288 module_name = default_name(dwfl_module_info(module, NULL,
50e0d793 289 &module_start, &module_end,
bd2b1e68
GH
290 NULL, NULL,
291 NULL, NULL),
292 "module");
50e0d793
GH
293
294 // Reset existing pointers and names
295
296 module_dwarf = NULL;
297
a229fcd7 298 cu_name.clear();
50e0d793
GH
299 cu = NULL;
300
a229fcd7 301 function_name.clear();
50e0d793 302 function = NULL;
bd2b1e68
GH
303 }
304
50e0d793 305
bd2b1e68
GH
306 void focus_on_cu(Dwarf_Die * c)
307 {
308 assert(c);
50e0d793
GH
309 assert(module);
310
bd2b1e68 311 cu = c;
50e0d793
GH
312 cu_name = default_name(dwarf_diename(c), "CU");
313
314 // Reset existing pointers and names
a229fcd7 315 function_name.clear();
50e0d793 316 function = NULL;
bd2b1e68
GH
317 }
318
50e0d793 319
bd2b1e68
GH
320 void focus_on_function(Dwarf_Func * f)
321 {
322 assert(f);
50e0d793
GH
323 assert(module);
324 assert(cu);
325
bd2b1e68 326 function = f;
7a053d3b 327 function_name = default_name(dwarf_func_name(function),
bd2b1e68 328 "function");
bd2b1e68
GH
329 }
330
50e0d793 331
bd2b1e68
GH
332 void focus_on_module_containing_global_address(Dwarf_Addr a)
333 {
334 assert(dwfl);
50e0d793 335 cu = NULL;
24cb178f 336 if (false && sess.verbose)
bd2b1e68
GH
337 clog << "focusing on module containing global addr " << a << endl;
338 focus_on_module(dwfl_addrmodule(dwfl, a));
339 }
340
50e0d793 341
7e1279ea 342 void query_cu_containing_global_address(Dwarf_Addr a, void *arg)
bd2b1e68 343 {
bd2b1e68 344 Dwarf_Addr bias;
50e0d793 345 assert(dwfl);
5227f1ea 346 get_module_dwarf();
aab2b35f 347 if (false && sess.verbose)
50e0d793 348 clog << "focusing on cu containing global addr " << a << endl;
7e1279ea 349 query_cu (dwfl_module_addrdie(module, a, &bias), arg);
bd2b1e68
GH
350 assert(bias == module_bias);
351 }
352
50e0d793 353
7e1279ea 354 void query_cu_containing_module_address(Dwarf_Addr a, void *arg)
bd2b1e68 355 {
7e1279ea 356 query_cu_containing_global_address(module_address_to_global(a), arg);
bd2b1e68
GH
357 }
358
50e0d793 359
bd2b1e68
GH
360 Dwarf_Addr module_address_to_global(Dwarf_Addr a)
361 {
50e0d793 362 assert(dwfl);
bd2b1e68 363 assert(module);
5227f1ea 364 get_module_dwarf();
c239d28c
GH
365 if (module_name == TOK_KERNEL)
366 return a;
367
db520b00
FCE
368 if (false && sess.verbose)
369 clog << "module addr " << hex << a
370 << " + module start " << module_start
371 << " -> global addr " << (a + module_start) << dec << endl;
50e0d793 372 return a + module_start;
bd2b1e68
GH
373 }
374
50e0d793 375
bd2b1e68
GH
376 Dwarf_Addr global_address_to_module(Dwarf_Addr a)
377 {
378 assert(module);
5227f1ea 379 get_module_dwarf();
db520b00
FCE
380 if (false && sess.verbose)
381 clog << "global addr " << a
382 << " - module start " << hex << module_start
383 << " -> module addr " << (a - module_start) << dec << endl;
bd2b1e68
GH
384 return a - module_bias;
385 }
386
387
388 bool module_name_matches(string pattern)
389 {
390 assert(module);
391 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
24cb178f 392 if (t && sess.verbose)
bd2b1e68 393 clog << "pattern '" << pattern << "' "
24cb178f 394 << "matches "
bd2b1e68
GH
395 << "module '" << module_name << "'" << endl;
396 return t;
397 }
398
50e0d793 399
bd2b1e68
GH
400 bool function_name_matches(string pattern)
401 {
402 assert(function);
403 bool t = (fnmatch(pattern.c_str(), function_name.c_str(), 0) == 0);
24cb178f 404 if (t && sess.verbose)
bd2b1e68 405 clog << "pattern '" << pattern << "' "
24cb178f 406 << "matches "
bd2b1e68
GH
407 << "function '" << function_name << "'" << endl;
408 return t;
409 }
410
50e0d793 411
bd2b1e68
GH
412 bool cu_name_matches(string pattern)
413 {
414 assert(cu);
415 bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
24cb178f 416 if (t && sess.verbose)
bd2b1e68 417 clog << "pattern '" << pattern << "' "
24cb178f 418 << "matches "
bd2b1e68
GH
419 << "CU '" << cu_name << "'" << endl;
420 return t;
421 }
422
50e0d793 423
7e1279ea 424 void dwfl_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
bd2b1e68 425 {
7e1279ea 426 string msg = "libdwfl failure (" + desc + "): ";
d8067b24
FCE
427 if (rc < 0) msg += dwfl_errmsg (rc);
428 else if (rc > 0) msg += strerror (rc);
bd2b1e68 429 if (rc != 0)
d8067b24 430 throw semantic_error (msg);
bd2b1e68
GH
431 }
432
7e1279ea
FCE
433 void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
434 {
435 string msg = "libdw failure (" + desc + "): ";
436 if (rc < 0) msg += dwarf_errmsg (rc);
437 else if (rc > 0) msg += strerror (rc);
438 if (rc != 0)
439 throw semantic_error (msg);
440 }
441
50e0d793 442
5227f1ea 443 dwflpp(systemtap_session & sess)
bd2b1e68 444 :
5227f1ea 445 sess(sess),
bd2b1e68
GH
446 dwfl(NULL),
447 module(NULL),
448 module_dwarf(NULL),
449 module_bias(0),
50e0d793
GH
450 module_start(0),
451 module_end(0),
bd2b1e68
GH
452 cu(NULL),
453 function(NULL)
454 {}
7a053d3b 455
50e0d793 456
bd2b1e68
GH
457 void setup(bool kernel)
458 {
b5d77020
FCE
459 // XXX: this is where the session -R parameter could come in
460 static char* debuginfo_path = "-:.debug:/usr/lib/debug";
461
bd2b1e68
GH
462 static const Dwfl_Callbacks proc_callbacks =
463 {
464 dwfl_linux_proc_find_elf,
465 dwfl_standard_find_debuginfo,
466 NULL,
b5d77020 467 & debuginfo_path
bd2b1e68 468 };
7a053d3b 469
bd2b1e68
GH
470 static const Dwfl_Callbacks kernel_callbacks =
471 {
472 dwfl_linux_kernel_find_elf,
473 dwfl_standard_find_debuginfo,
474 dwfl_linux_kernel_module_section_address,
b5d77020 475 & debuginfo_path
bd2b1e68
GH
476 };
477
478 if (kernel)
479 {
7e1279ea 480 dwfl = dwfl_begin (&kernel_callbacks);
bd2b1e68 481 if (!dwfl)
7e1279ea
FCE
482 throw semantic_error ("cannot open dwfl");
483 dwfl_report_begin (dwfl);
d8067b24
FCE
484 // XXX: if we have only kernel.* probe points, we shouldn't waste time
485 // looking for module debug-info (and vice versa).
7e1279ea
FCE
486 dwfl_assert ("dwfl_linux_kernel_report_kernel",
487 dwfl_linux_kernel_report_kernel (dwfl));
488 dwfl_assert ("dwfl_linux_kernel_report_modules",
489 dwfl_linux_kernel_report_modules (dwfl));
bd2b1e68
GH
490 }
491 else
492 {
7e1279ea
FCE
493 dwfl = dwfl_begin (&proc_callbacks);
494 dwfl_report_begin (dwfl);
bd2b1e68 495 if (!dwfl)
7e1279ea 496 throw semantic_error ("cannot open dwfl");
bd2b1e68
GH
497 // XXX: Find pids or processes, do userspace stuff.
498 }
499
7e1279ea 500 dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
bd2b1e68
GH
501 }
502
503 void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
504 const char *, Dwarf_Addr,
77de5e9e 505 void *),
bd2b1e68
GH
506 void * data)
507 {
bd2b1e68
GH
508 ptrdiff_t off = 0;
509 do
510 {
77de5e9e 511 off = dwfl_getmodules (dwfl, callback, data, off);
bd2b1e68
GH
512 }
513 while (off > 0);
7e1279ea 514 dwfl_assert("dwfl_getmodules", off);
bd2b1e68
GH
515 }
516
7e1279ea 517
7a053d3b 518 void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
bd2b1e68
GH
519 void * data)
520 {
5227f1ea
GH
521 get_module_dwarf();
522
bd2b1e68
GH
523 if (!module_dwarf)
524 {
525 cerr << "WARNING: no dwarf info found for module " << module_name << endl;
526 return;
527 }
528
bd2b1e68
GH
529 Dwarf *dw = module_dwarf;
530 Dwarf_Off off = 0;
531 size_t cuhl;
532 Dwarf_Off noff;
7e1279ea 533 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
7a053d3b 534 {
bd2b1e68
GH
535 Dwarf_Die die_mem;
536 Dwarf_Die *die;
7e1279ea
FCE
537 die = dwarf_offdie (dw, off + cuhl, &die_mem);
538 if (callback (die, data) != DWARF_CB_OK)
bd2b1e68
GH
539 break;
540 off = noff;
541 }
542 }
543
bd2b1e68 544
7e1279ea 545 bool func_is_inline()
bd2b1e68 546 {
7e1279ea
FCE
547 assert (function);
548 return dwarf_func_inline (function) != 0;
bd2b1e68
GH
549 }
550
7e1279ea
FCE
551 void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
552 void * data)
bd2b1e68 553 {
7e1279ea
FCE
554 assert (function);
555 assert (func_is_inline ());
556 dwarf_assert ("dwarf_func_inline_instances",
557 dwarf_func_inline_instances (function, callback, data));
4fa7b22b 558 }
bd2b1e68 559
50e0d793 560
7e1279ea
FCE
561 void iterate_over_functions (int (* callback)(Dwarf_Func * func, void * arg),
562 void * data)
4fa7b22b 563 {
7e1279ea
FCE
564 assert (module);
565 assert (cu);
566 dwarf_getfuncs (cu, callback, data, 0);
567 }
c239d28c 568
d9b516ca 569
7e1279ea
FCE
570 void iterate_over_srcfile_lines (char const * srcfile,
571 int lineno,
572 void (* callback) (Dwarf_Line * line, void * arg),
573 void *data)
574 {
6315bd76
GH
575 Dwarf_Line **srcsp = NULL;
576 size_t nsrcs = 0;
bb788f9f 577
7e1279ea 578 get_module_dwarf();
bb788f9f 579
7e1279ea
FCE
580 dwarf_assert ("dwarf_getsrc_file",
581 dwarf_getsrc_file (module_dwarf,
582 srcfile, lineno, 0,
583 &srcsp, &nsrcs));
6315bd76 584 try
bb788f9f 585 {
6315bd76
GH
586 for (size_t i = 0; i < nsrcs; ++i)
587 {
588 callback (srcsp[i], data);
589 }
bb788f9f 590 }
6315bd76
GH
591 catch (...)
592 {
593 free (srcsp);
594 throw;
595 }
596 free (srcsp);
50e0d793
GH
597 }
598
599
7e1279ea
FCE
600 void collect_srcfiles_matching (string const & pattern,
601 set<char const *> & filtered_srcfiles)
50e0d793 602 {
7e1279ea
FCE
603 assert (module);
604 assert (cu);
bb788f9f 605
7e1279ea
FCE
606 size_t nfiles;
607 Dwarf_Files *srcfiles;
bb788f9f 608
7e1279ea
FCE
609 dwarf_assert ("dwarf_getsrcfiles",
610 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
611 {
612 for (size_t i = 0; i < nfiles; ++i)
50e0d793 613 {
7e1279ea
FCE
614 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
615 if (fnmatch (pattern.c_str(), fname, 0) == 0)
50e0d793 616 {
7e1279ea
FCE
617 filtered_srcfiles.insert (fname);
618 if (sess.verbose)
619 clog << "selected source file '" << fname << "'" << endl;
50e0d793
GH
620 }
621 }
7e1279ea
FCE
622 }
623 }
50e0d793 624
7e1279ea
FCE
625 void resolve_prologue_endings (map<Dwarf_Addr, func_info> & funcs)
626 {
627 assert(module);
628 assert(cu);
50e0d793 629
7e1279ea
FCE
630 size_t nlines;
631 Dwarf_Lines *lines;
632 Dwarf_Addr previous_addr;
bb788f9f 633 bool choose_next_line = false;
4fa7b22b 634
7e1279ea
FCE
635 dwarf_assert ("dwarf_getsrclines",
636 dwarf_getsrclines(cu, &lines, &nlines));
637
50e0d793
GH
638 for (size_t i = 0; i < nlines; ++i)
639 {
7e1279ea 640 Dwarf_Addr addr;
50e0d793 641 Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
7e1279ea
FCE
642 dwarf_lineaddr (line_rec, &addr);
643
50e0d793
GH
644 if (choose_next_line)
645 {
7e1279ea
FCE
646 map<Dwarf_Addr, func_info>::iterator i = funcs.find (previous_addr);
647 assert (i != funcs.end());
648 i->second.prologue_end = addr;
649 choose_next_line = false;
650 }
651
652 else
653 {
654 map<Dwarf_Addr, func_info>::const_iterator i = funcs.find (addr);
655 if (i != funcs.end())
656 choose_next_line = true;
50e0d793 657 }
7e1279ea 658 previous_addr = addr;
50e0d793 659 }
bd2b1e68
GH
660 }
661
7e1279ea
FCE
662
663 bool function_entrypc (Dwarf_Addr * addr)
664 {
665 assert (function);
666 return (dwarf_func_entrypc (function, addr) == 0);
667 }
668
669
670 bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
671 {
672 Dwarf_Attribute attr_mem;
673 Dwarf_Attribute *attr = dwarf_attr (die, DW_AT_entry_pc, &attr_mem);
674 if (attr != NULL)
675 return (dwarf_formaddr (attr, addr) == 0);
676
677 return ( dwarf_lowpc (die, addr) == 0);
678 }
679
4cd232e4
GH
680 void function_die (Dwarf_Die *d)
681 {
682 assert (function);
683 dwarf_func_die (function, d);
684 }
7e1279ea 685
4cd232e4 686 void function_file (char const ** c)
7e1279ea
FCE
687 {
688 assert (function);
4cd232e4
GH
689 assert (c);
690 *c = dwarf_func_file (function);
7e1279ea
FCE
691 }
692
4cd232e4 693 void function_line (int *linep)
7e1279ea
FCE
694 {
695 assert (function);
4cd232e4 696 dwarf_func_line (function, linep);
7e1279ea
FCE
697 }
698
699 bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
700 {
701 int res = dwarf_haspc (die, pc);
702 if (res == -1)
703 dwarf_assert ("dwarf_haspc", res);
704 return res == 1;
705 }
706
707
e36387d7
RM
708 static void loc2c_error (void *arg, const char *fmt, ...)
709 {
710 char *msg = NULL;
711 va_list ap;
712 va_start (ap, fmt);
713 vasprintf (&msg, fmt, ap);
714 va_end (ap);
715 throw semantic_error (msg);
716 }
bd2b1e68 717
7e1279ea 718
4b1ad75e
RM
719 static void loc2c_emit_address (void *arg, struct obstack *pool,
720 Dwarf_Addr address)
721 {
722 dwflpp *dwfl = (dwflpp *) arg;
723 obstack_printf (pool, "%#" PRIx64 "UL /* hard-coded %s address */",
724 address, dwfl_module_info (dwfl->module, NULL, NULL, NULL,
725 NULL, NULL, NULL, NULL));
726 }
727
6e95311e 728 string literal_stmt_for_local(Dwarf_Addr pc,
91eefb1c 729 string const & local,
d9b516ca 730 vector<pair<target_symbol::component_type,
fdfbe4f7
GH
731 std::string> > const & components,
732 exp_type & ty)
77de5e9e
GH
733 {
734 assert (cu);
735
736 Dwarf_Die *scopes;
737 Dwarf_Die vardie;
738
6e95311e 739 int nscopes = dwarf_getscopes (cu, pc, &scopes);
77de5e9e
GH
740 if (nscopes == 0)
741 {
7a053d3b 742 throw semantic_error ("unable to find any scopes containing "
59ff2773 743 + lex_cast_hex<string>(pc)
77de5e9e
GH
744 + " while searching for local '" + local + "'");
745 }
7a053d3b 746
77de5e9e 747 int declaring_scope = dwarf_getscopevar (scopes, nscopes,
7a053d3b
RM
748 local.c_str(),
749 0, NULL, 0, 0,
750 &vardie);
77de5e9e
GH
751 if (declaring_scope < 0)
752 {
753 throw semantic_error ("unable to find local '" + local + "'"
59ff2773 754 + " near pc " + lex_cast_hex<string>(pc));
77de5e9e 755 }
7a053d3b 756
77de5e9e
GH
757 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
758 for (int inner = 0; inner < nscopes; ++inner)
759 {
760 switch (dwarf_tag (&scopes[inner]))
761 {
762 default:
763 continue;
764 case DW_TAG_subprogram:
765 case DW_TAG_entry_point:
766 case DW_TAG_inlined_subroutine: /* XXX */
767 if (inner >= declaring_scope)
768 fb_attr = dwarf_attr_integrate (&scopes[inner],
769 DW_AT_frame_base,
770 &fb_attr_mem);
771 break;
772 }
773 }
774
775 if (sess.verbose)
7a053d3b 776 clog << "finding location for local '" << local
db520b00
FCE
777 << "' near address " << hex << pc
778 << ", module bias " << module_bias << dec
77de5e9e 779 << endl;
7a053d3b
RM
780
781 Dwarf_Attribute attr_mem;
77de5e9e 782 if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
7e1279ea
FCE
783 {
784 throw semantic_error("failed to retrieve location "
785 "attribute for local '" + local
786 + "' (dieoffset: "
787 + lex_cast_hex<string>(dwarf_dieoffset (&vardie))
788 + ")");
789 }
7a053d3b 790
77de5e9e
GH
791#define obstack_chunk_alloc malloc
792#define obstack_chunk_free free
7a053d3b 793
77de5e9e 794 struct obstack pool;
7a053d3b 795 obstack_init (&pool);
77de5e9e 796 struct location *tail = NULL;
e36387d7 797 struct location *head = c_translate_location (&pool, &loc2c_error, this,
4b1ad75e 798 &loc2c_emit_address,
e36387d7 799 1, module_bias,
77de5e9e
GH
800 &attr_mem, pc,
801 &tail, fb_attr);
802
d9b516ca 803 if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
77de5e9e
GH
804 throw semantic_error("failed to retrieve type "
805 "attribute for local '" + local + "'");
806
d9b516ca
RM
807 Dwarf_Die die_mem, *die = &vardie;
808 unsigned i = 0;
809 while (i < components.size())
810 {
811 die = dwarf_formref_die (&attr_mem, &die_mem);
812 const int typetag = dwarf_tag (die);
813 switch (typetag)
814 {
815 case DW_TAG_typedef:
fdfbe4f7
GH
816 case DW_TAG_const_type:
817 case DW_TAG_volatile_type:
d9b516ca
RM
818 /* Just iterate on the referent type. */
819 break;
91eefb1c 820
d9b516ca
RM
821 case DW_TAG_pointer_type:
822 if (components[i].first == target_symbol::comp_literal_array_index)
823 goto subscript;
91eefb1c 824
d9b516ca
RM
825 c_translate_pointer (&pool, 1, module_bias, die, &tail);
826 break;
91eefb1c 827
d9b516ca
RM
828 case DW_TAG_array_type:
829 if (components[i].first == target_symbol::comp_literal_array_index)
830 {
831 subscript:
832 c_translate_array (&pool, 1, module_bias, die, &tail,
833 NULL, lex_cast<Dwarf_Word>(components[i].second));
834 ++i;
835 }
836 else
837 throw semantic_error("bad field '"
838 + components[i].second
839 + "' for array type");
840 break;
91eefb1c 841
d9b516ca
RM
842 case DW_TAG_structure_type:
843 case DW_TAG_union_type:
844 switch (dwarf_child (die, &die_mem))
845 {
846 case 1: /* No children. */
847 throw semantic_error ("empty struct "
848 + string (dwarf_diename_integrate (die) ?: "<anonymous>"));
849 break;
850 case -1: /* Error. */
851 default: /* Shouldn't happen */
852 throw semantic_error (string (typetag == DW_TAG_union_type ? "union" : "struct")
853 + string (dwarf_diename_integrate (die) ?: "<anonymous>")
854 + string (dwarf_errmsg (-1)));
855 break;
856
857 case 0:
858 break;
859 }
860
861 while (dwarf_tag (die) != DW_TAG_member
862 || ({ const char *member = dwarf_diename_integrate (die);
863 member == NULL || string(member) != components[i].second; }))
864 if (dwarf_siblingof (die, &die_mem) != 0)
865 throw semantic_error ("field name " + components[i].second + " not found");
866
867 if (dwarf_attr_integrate (die, DW_AT_data_member_location,
868 &attr_mem) == NULL)
869 {
870 /* Union members don't usually have a location,
871 but just use the containing union's location. */
872 if (typetag != DW_TAG_union_type)
873 throw semantic_error ("no location for field "
874 + components[i].second
875 + " :" + string(dwarf_errmsg (-1)));
876 }
877 else
4b1ad75e 878 c_translate_location (&pool, NULL, NULL, NULL, 1,
e36387d7 879 module_bias, &attr_mem, pc,
d9b516ca
RM
880 &tail, NULL);
881 ++i;
882 break;
883
884 case DW_TAG_base_type:
885 throw semantic_error ("field "
886 + components[i].second
887 + " vs base type "
888 + string(dwarf_diename_integrate (die) ?: "<anonymous type>"));
889 break;
890 case -1:
891 throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)));
892 break;
893
894 default:
895 throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>")
896 + ": unexpected type tag "
897 + lex_cast<string>(dwarf_tag (die)));
898 break;
899 }
900
901 /* Now iterate on the type in DIE's attribute. */
902 if (dwarf_attr_integrate (die, DW_AT_type, &attr_mem) == NULL)
903 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
904 }
91eefb1c 905
d9b516ca
RM
906 /* Fetch the type DIE corresponding to the final location to be accessed.
907 It must be a base type or a typedef for one. */
908
909 Dwarf_Die typedie_mem;
910 Dwarf_Die *typedie;
911 int typetag;
912 while (1)
913 {
914 typedie = dwarf_formref_die (&attr_mem, &typedie_mem);
915 if (typedie == NULL)
916 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
917 typetag = dwarf_tag (typedie);
fdfbe4f7
GH
918 if (typetag != DW_TAG_typedef &&
919 typetag != DW_TAG_const_type &&
920 typetag != DW_TAG_volatile_type)
91eefb1c 921 break;
d9b516ca
RM
922 if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL)
923 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
924 }
91eefb1c 925
91eefb1c 926
fdfbe4f7
GH
927 // If we have a base type, we will fetch it into pe_long.
928 //
929 // If we have a pointer to non-char, we will cast it to uintptr_t, and fetch
930 // into pe_long.
931 //
932 // If we have a pointer to char, we will fetch into pe_string, using
933 // deref_string() over in loc2c-runtime.h
934
935 string prelude, postlude;
936 switch (typetag)
937 {
fdfbe4f7 938 default:
66d284f4
FCE
939 throw semantic_error ("unsupported type tag "
940 + lex_cast<string>(typetag));
fdfbe4f7 941 break;
66d284f4 942
e7a012f0 943 case DW_TAG_enumeration_type:
fdfbe4f7
GH
944 case DW_TAG_base_type:
945 ty = pe_long;
946 c_translate_fetch (&pool, 1, module_bias, die, typedie, &tail,
947 "THIS->__retvalue");
948 break;
949
950 case DW_TAG_array_type:
951 case DW_TAG_pointer_type:
952 {
953 Dwarf_Die pointee_typedie_mem;
954 Dwarf_Die *pointee_typedie;
955 Dwarf_Word pointee_encoding;
246b383e 956 Dwarf_Word pointee_byte_size = 0;
fdfbe4f7
GH
957 int pointee_typetag;
958
959 if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL)
960 throw semantic_error ("cannot get type of pointer: " + string(dwarf_errmsg (-1)));
961
962 while (1)
963 {
964 pointee_typedie = dwarf_formref_die (&attr_mem, &pointee_typedie_mem);
965
966 if (pointee_typedie == NULL)
967 throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)));
968
969 pointee_typetag = dwarf_tag (pointee_typedie);
970
971 if (pointee_typetag != DW_TAG_typedef &&
972 pointee_typetag != DW_TAG_const_type &&
973 pointee_typetag != DW_TAG_volatile_type)
974 break;
975 if (dwarf_attr_integrate (pointee_typedie, DW_AT_type, &attr_mem) == NULL)
976 throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)));
977 }
246b383e
GH
978
979 if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, &attr_mem))
980 dwarf_formudata (&attr_mem, &pointee_byte_size);
fdfbe4f7
GH
981
982 dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, &attr_mem),
983 &pointee_encoding);
984
f9eba66e
FCE
985 // We have the pointer: cast it to an integral type via &(*(...))
986
987 // NB: per bug #1187, at one point char*-like types were
988 // automagically converted here to systemtap string values.
989 // For several reasons, this was taken back out, leaving
990 // pointer-to-string "conversion" (copying) to tapset functions.
991
992 ty = pe_long;
993 if (typetag == DW_TAG_array_type)
994 c_translate_array (&pool, 1, module_bias, typedie, &tail, NULL, 0);
fdfbe4f7 995 else
f9eba66e
FCE
996 c_translate_pointer (&pool, 1, module_bias, typedie, &tail);
997 c_translate_addressof (&pool, 1, module_bias, NULL, pointee_typedie, &tail,
998 "THIS->__retvalue");
fdfbe4f7
GH
999 }
1000 break;
1001 }
f9eba66e 1002
77de5e9e
GH
1003 size_t bufsz = 1024;
1004 char *buf = static_cast<char*>(malloc(bufsz));
1005 assert(buf);
f9eba66e 1006
77de5e9e
GH
1007 FILE *memstream = open_memstream (&buf, &bufsz);
1008 assert(memstream);
7a053d3b 1009
fdfbe4f7
GH
1010 fprintf(memstream, "{\n");
1011 fprintf(memstream, prelude.c_str());
77de5e9e 1012 bool deref = c_emit_location (memstream, head, 1);
fdfbe4f7 1013 fprintf(memstream, postlude.c_str());
a781f401 1014 fprintf(memstream, " goto out;\n");
7a053d3b 1015
a781f401
FCE
1016 // dummy use of deref_fault label, to disable warning if deref() not used
1017 fprintf(memstream, "if (0) goto deref_fault;\n");
1018
1019 // XXX: deref flag not reliable; emit fault label unconditionally
1020 if (deref) ;
1021 fprintf(memstream,
1022 "deref_fault:\n"
5e309481 1023 " c->last_error = \"pointer dereference fault\";\n"
a781f401 1024 " goto out;\n");
fdfbe4f7 1025 fprintf(memstream, "}\n");
7a053d3b 1026
77de5e9e
GH
1027 fclose (memstream);
1028 string result(buf);
1029 free (buf);
1030 return result;
1031 }
7a053d3b
RM
1032
1033
77de5e9e 1034
bd2b1e68
GH
1035 ~dwflpp()
1036 {
1037 if (dwfl)
1038 dwfl_end(dwfl);
1039 }
1040};
1041
20c6c071 1042
7a053d3b 1043enum
bd2b1e68 1044function_spec_type
7a053d3b 1045 {
bd2b1e68
GH
1046 function_alone,
1047 function_and_file,
7a053d3b 1048 function_file_and_line
bd2b1e68
GH
1049 };
1050
ec4373ff 1051
bd2b1e68 1052struct dwarf_builder;
77de5e9e
GH
1053struct dwarf_query;
1054
bd2b1e68 1055struct dwarf_derived_probe : public derived_probe
b55bc428 1056{
4cd232e4
GH
1057 dwarf_derived_probe (string const & funcname,
1058 char const * filename,
1059 int line,
1060 Dwarf_Addr addr,
1061 dwarf_query & q);
d9b516ca 1062
20c6c071 1063 Dwarf_Addr addr;
a229fcd7 1064 Dwarf_Addr module_bias;
fd6602a0 1065 bool has_return;
7a053d3b 1066
bd2b1e68 1067 // Pattern registration helpers.
7a053d3b 1068 static void register_relative_variants(match_node * root,
bd2b1e68 1069 dwarf_builder * dw);
7a053d3b 1070 static void register_statement_variants(match_node * root,
bd2b1e68 1071 dwarf_builder * dw);
fd6602a0
FCE
1072 static void register_function_variants(match_node * root,
1073 dwarf_builder * dw);
7a053d3b 1074 static void register_function_and_statement_variants(match_node * root,
bd2b1e68 1075 dwarf_builder * dw);
20c6c071 1076 static void register_patterns(match_node * root);
7a053d3b 1077
20c6c071
GH
1078 virtual void emit_registrations (translator_output * o, unsigned i);
1079 virtual void emit_deregistrations (translator_output * o, unsigned i);
1080 virtual void emit_probe_entries (translator_output * o, unsigned i);
20c6c071
GH
1081};
1082
1083// Helper struct to thread through the dwfl callbacks.
7a053d3b 1084struct
20c6c071
GH
1085dwarf_query
1086{
5227f1ea
GH
1087 dwarf_query(systemtap_session & sess,
1088 probe * base_probe,
20c6c071
GH
1089 probe_point * base_loc,
1090 dwflpp & dw,
1091 map<string, literal *> const & params,
1092 vector<derived_probe *> & results);
bd2b1e68 1093
5227f1ea
GH
1094 systemtap_session & sess;
1095
bd2b1e68 1096 // Parameter extractors.
7a053d3b 1097 static bool has_null_param(map<string, literal *> const & params,
bd2b1e68 1098 string const & k);
7a053d3b 1099 static bool get_string_param(map<string, literal *> const & params,
bd2b1e68 1100 string const & k, string & v);
7a053d3b 1101 static bool get_number_param(map<string, literal *> const & params,
bd2b1e68 1102 string const & k, long & v);
c239d28c
GH
1103 static bool get_number_param(map<string, literal *> const & params,
1104 string const & k, Dwarf_Addr & v);
b55bc428 1105
77de5e9e
GH
1106 string pt_regs_member_for_regnum(uint8_t dwarf_regnum);
1107
20c6c071 1108 vector<derived_probe *> & results;
20c6c071
GH
1109
1110 bool has_kernel;
1111 bool has_process;
1112 bool has_module;
7a053d3b
RM
1113 string process_val;
1114 string module_val;
1115 string function_val;
20c6c071
GH
1116
1117 bool has_function_str;
1118 bool has_statement_str;
1119 bool has_function_num;
1120 bool has_statement_num;
7a053d3b
RM
1121 string statement_str_val;
1122 string function_str_val;
c239d28c
GH
1123 Dwarf_Addr statement_num_val;
1124 Dwarf_Addr function_num_val;
20c6c071
GH
1125
1126 bool has_callees;
7a053d3b 1127 long callee_val;
20c6c071
GH
1128
1129 bool has_return;
1130
1131 bool has_label;
1132 string label_val;
1133
1134 bool has_relative;
1135 long relative_val;
1136
1137 function_spec_type parse_function_spec(string & spec);
1138 function_spec_type spec_type;
1139 string function;
1140 string file;
1141 int line;
1142
7e1279ea
FCE
1143 set<char const *> filtered_srcfiles;
1144
1145 // Map official entrypc -> func_info object
1146 map<Dwarf_Addr, inline_instance_info> filtered_inlines;
1147 map<Dwarf_Addr, func_info> filtered_functions;
1148 bool choose_next_line;
1149 Dwarf_Addr entrypc_for_next_line;
1150
20c6c071
GH
1151 probe * base_probe;
1152 probe_point * base_loc;
1153 dwflpp & dw;
b55bc428
FCE
1154};
1155
98afd80e
FCE
1156
1157struct dwarf_builder: public derived_probe_builder
b55bc428 1158{
bd2b1e68 1159 dwarf_builder() {}
5227f1ea 1160 virtual void build(systemtap_session & sess,
7a053d3b 1161 probe * base,
20c6c071
GH
1162 probe_point * location,
1163 std::map<std::string, literal *> const & parameters,
1164 vector<probe *> & results_to_expand_further,
1165 vector<derived_probe *> & finished_results);
b55bc428
FCE
1166};
1167
7a053d3b
RM
1168bool
1169dwarf_query::has_null_param(map<string, literal *> const & params,
20c6c071 1170 string const & k)
bd2b1e68
GH
1171{
1172 map<string, literal *>::const_iterator i = params.find(k);
1173 if (i != params.end() && i->second == NULL)
1174 return true;
1175 return false;
1176}
1177
7a053d3b
RM
1178bool
1179dwarf_query::get_string_param(map<string, literal *> const & params,
20c6c071 1180 string const & k, string & v)
bd2b1e68 1181{
98afd80e 1182 return derived_probe_builder::get_param (params, k, v);
bd2b1e68
GH
1183}
1184
7a053d3b
RM
1185bool
1186dwarf_query::get_number_param(map<string, literal *> const & params,
20c6c071 1187 string const & k, long & v)
bd2b1e68 1188{
98afd80e
FCE
1189 int64_t value;
1190 bool present = derived_probe_builder::get_param (params, k, value);
1191 v = (long) value;
1192 return present;
bd2b1e68
GH
1193}
1194
c239d28c
GH
1195bool
1196dwarf_query::get_number_param(map<string, literal *> const & params,
1197 string const & k, Dwarf_Addr & v)
1198{
98afd80e
FCE
1199 int64_t value;
1200 bool present = derived_probe_builder::get_param (params, k, value);
1201 v = (Dwarf_Addr) value;
1202 return present;
c239d28c
GH
1203}
1204
77de5e9e 1205
5227f1ea
GH
1206dwarf_query::dwarf_query(systemtap_session & sess,
1207 probe * base_probe,
20c6c071
GH
1208 probe_point * base_loc,
1209 dwflpp & dw,
1210 map<string, literal *> const & params,
1211 vector<derived_probe *> & results)
5227f1ea
GH
1212 : sess(sess),
1213 results(results),
7a053d3b 1214 base_probe(base_probe),
20c6c071
GH
1215 base_loc(base_loc),
1216 dw(dw)
bd2b1e68 1217{
20c6c071 1218
bd2b1e68
GH
1219 // Reduce the query to more reasonable semantic values (booleans,
1220 // extracted strings, numbers, etc).
1221
1222 has_kernel = has_null_param(params, TOK_KERNEL);
1223 has_module = get_string_param(params, TOK_MODULE, module_val);
1224 has_process = get_string_param(params, TOK_PROCESS, process_val);
1225
1226 has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
1227 has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
1228
1229 has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
1230 has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
1231
1232 callee_val = 1;
7a053d3b 1233 has_callees = (has_null_param(params, TOK_CALLEES) ||
bd2b1e68
GH
1234 get_number_param(params, TOK_CALLEES, callee_val));
1235
1236 has_return = has_null_param(params, TOK_RETURN);
1237
1238 has_label = get_string_param(params, TOK_LABEL, label_val);
1239 has_relative = get_number_param(params, TOK_RELATIVE, relative_val);
7a053d3b 1240
bd2b1e68
GH
1241 if (has_function_str)
1242 spec_type = parse_function_spec(function_str_val);
1243 else if (has_statement_str)
1244 spec_type = parse_function_spec(statement_str_val);
7a053d3b 1245}
bd2b1e68
GH
1246
1247
bd2b1e68 1248function_spec_type
20c6c071 1249dwarf_query::parse_function_spec(string & spec)
bd2b1e68
GH
1250{
1251 string::const_iterator i = spec.begin(), e = spec.end();
7a053d3b 1252
bd2b1e68
GH
1253 function.clear();
1254 file.clear();
1255 line = 0;
1256
1257 while (i != e && *i != '@')
1258 {
1259 if (*i == ':')
1260 goto bad;
1261 function += *i++;
1262 }
1263
1264 if (i == e)
1265 {
5227f1ea 1266 if (sess.verbose)
7a053d3b
RM
1267 clog << "parsed '" << spec
1268 << "' -> func '" << function
bd2b1e68
GH
1269 << "'" << endl;
1270 return function_alone;
1271 }
1272
1273 if (i++ == e)
1274 goto bad;
1275
1276 while (i != e && *i != ':')
1277 file += *i++;
7a053d3b 1278
bd2b1e68
GH
1279 if (i == e)
1280 {
5227f1ea 1281 if (sess.verbose)
7a053d3b
RM
1282 clog << "parsed '" << spec
1283 << "' -> func '"<< function
1284 << "', file '" << file
bd2b1e68
GH
1285 << "'" << endl;
1286 return function_and_file;
1287 }
1288
1289 if (i++ == e)
1290 goto bad;
1291
1292 try
1293 {
1294 line = lex_cast<int>(string(i, e));
5227f1ea 1295 if (sess.verbose)
7a053d3b
RM
1296 clog << "parsed '" << spec
1297 << "' -> func '"<< function
1298 << "', file '" << file
bd2b1e68
GH
1299 << "', line " << line << endl;
1300 return function_file_and_line;
1301 }
1302 catch (runtime_error & exn)
1303 {
1304 goto bad;
1305 }
1306
1307 bad:
7a053d3b 1308 throw semantic_error("malformed specification '" + spec + "'",
20c6c071 1309 base_probe->tok);
bd2b1e68
GH
1310}
1311
1312
7e1279ea
FCE
1313
1314 // The critical determining factor when interpreting a pattern
1315 // string is, perhaps surprisingly: "presence of a lineno". The
1316 // presence of a lineno changes the search strategy completely.
1317 //
1318 // Compare the two cases:
1319 //
1320 // 1. {statement,function}(foo@file.c:lineno)
1321 // - find the files matching file.c
1322 // - in each file, find the functions matching foo
1323 // - query the file for line records matching lineno
1324 // - iterate over the line records,
1325 // - and iterate over the functions,
1326 // - if(haspc(function.DIE, line.addr))
1327 // - if looking for statements: probe(lineno.addr)
1328 // - if looking for functions: probe(function.{entrypc,return,etc.})
1329 //
1330 // 2. {statement,function}(foo@file.c)
1331 // - find the files matching file.c
1332 // - in each file, find the functions matching foo
1333 // - probe(function.{entrypc,return,etc.})
1334 //
1335 // Thus the first decision we make is based on the presence of a
1336 // lineno, and we enter entirely different sets of callbacks
1337 // depending on that decision.
1338
1339
bd2b1e68 1340static void
4cd232e4
GH
1341query_statement (string const & func,
1342 char const * file,
1343 int line,
1344 Dwarf_Addr stmt_addr,
1345 dwarf_query * q)
bd2b1e68 1346{
39bcd429
FCE
1347 try
1348 {
1349 // XXX: implement
1350 if (q->has_relative)
1351 throw semantic_error("incomplete: do not know how to interpret .relative",
1352 q->base_probe->tok);
d9b516ca 1353
6e95311e 1354 q->results.push_back(new dwarf_derived_probe(func, file, line, stmt_addr, *q));
39bcd429
FCE
1355 }
1356 catch (const semantic_error& e)
1357 {
1358 q->sess.print_error (e);
1359 }
bd2b1e68
GH
1360}
1361
7e1279ea
FCE
1362static void
1363query_inline_instance_info (Dwarf_Addr entrypc,
6e95311e 1364 inline_instance_info const & ii,
7e1279ea
FCE
1365 dwarf_query * q)
1366{
1367 if (q->has_return)
1368 {
1369 throw semantic_error ("cannot probe .return of inline function '" + ii.name + "'");
1370 }
1371 else
1372 {
1373 if (q->sess.verbose)
1374 clog << "querying entrypc "
1375 << hex << entrypc << dec
1376 << " of instance of inline '" << ii.name << "'" << endl;
6e95311e 1377 query_statement (ii.name, ii.decl_file, ii.decl_line, entrypc, q);
7e1279ea
FCE
1378 }
1379}
1380
1381static void
1382query_func_info (Dwarf_Addr entrypc,
6e95311e 1383 func_info const & fi,
7e1279ea
FCE
1384 dwarf_query * q)
1385{
1386 if (q->has_return)
1387 {
1388 // NB. dwarf_derived_probe::emit_registrations will emit a
1389 // kretprobe based on the entrypc in this case.
1390 if (q->sess.verbose)
6e95311e
FCE
1391 clog << "querying entrypc of function '" << fi.name << "' for return probe" << endl;
1392 query_statement (fi.name, fi.decl_file, fi.decl_line, entrypc, q);
7e1279ea
FCE
1393 }
1394 else
1395 {
1396 if (q->sess.verbose)
6e95311e
FCE
1397 clog << "querying prologue-end of function '" << fi.name << "'" << endl;
1398 query_statement (fi.name, fi.decl_file, fi.decl_line, fi.prologue_end, q);
7e1279ea
FCE
1399 }
1400}
1401
1402
1403static void
1404query_srcfile_line (Dwarf_Line * line, void * arg)
1405{
1406 dwarf_query * q = static_cast<dwarf_query *>(arg);
1407
1408 Dwarf_Addr addr;
1409 dwarf_lineaddr(line, &addr);
4cd232e4 1410
7e1279ea
FCE
1411 for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
1412 i != q->filtered_functions.end(); ++i)
1413 {
1414 if (q->dw.die_has_pc (&(i->second.die), addr))
1415 {
1416 if (q->sess.verbose)
1417 clog << "function DIE lands on srcfile" << endl;
4cd232e4 1418 if (q->has_statement_str)
6e95311e 1419 query_statement (i->second.name, i->second.decl_file, q->line, addr, q);
4cd232e4
GH
1420 else
1421 query_func_info (i->first, i->second, q);
7e1279ea
FCE
1422 }
1423 }
1424
6e95311e 1425 for (map<Dwarf_Addr, inline_instance_info>::iterator i = q->filtered_inlines.begin();
4cd232e4 1426 i != q->filtered_inlines.end(); ++i)
7e1279ea 1427 {
4cd232e4
GH
1428 if (q->dw.die_has_pc (&(i->second.die), addr))
1429 {
1430 if (q->sess.verbose)
1431 clog << "inline instance DIE lands on srcfile" << endl;
1432 if (q->has_statement_str)
6e95311e 1433 query_statement (i->second.name, i->second.decl_file, q->line, addr, q);
4cd232e4
GH
1434 else
1435 query_inline_instance_info (i->first, i->second, q);
1436 }
1437 }
7e1279ea
FCE
1438}
1439
1440
4fa7b22b 1441static int
7e1279ea 1442query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
4fa7b22b
GH
1443{
1444 dwarf_query * q = static_cast<dwarf_query *>(arg);
7e1279ea 1445 assert (!q->has_statement_num);
bd2b1e68 1446
39bcd429 1447 try
7a053d3b 1448 {
bb788f9f 1449
7e1279ea
FCE
1450 bool record_this_inline = false;
1451
1452 if (q->sess.verbose)
1453 clog << "examining inline instance of " << q->dw.function_name << endl;
1454
1455 if (q->has_function_str || q->has_statement_str)
1456 record_this_inline = true;
1457 else if (q->has_function_num)
1458 {
1459 Dwarf_Addr query_addr = q->function_num_val;
1460
1461 if (q->has_module)
1462 query_addr = q->dw.module_address_to_global(query_addr);
1463
1464 if (q->dw.die_has_pc (die, query_addr))
1465 record_this_inline = true;
1466 }
1467
1468 if (record_this_inline)
1469 {
1470 if (q->sess.verbose)
1471 clog << "selected inline instance of " << q->dw.function_name << endl;
1472
1473 Dwarf_Addr entrypc;
1474 if (q->dw.die_entrypc (die, &entrypc))
1475 {
1476 inline_instance_info inl;
1477 inl.die = *die;
1478 inl.name = q->dw.function_name;
4cd232e4
GH
1479 q->dw.function_file (&inl.decl_file);
1480 q->dw.function_line (&inl.decl_line);
7e1279ea
FCE
1481 q->filtered_inlines[entrypc] = inl;
1482 }
1483 }
1484 return DWARF_CB_OK;
1485 }
1486 catch (const semantic_error& e)
1487 {
1488 q->sess.print_error (e);
1489 return DWARF_CB_ABORT;
1490 }
1491}
bb788f9f 1492
7e1279ea
FCE
1493static int
1494query_dwarf_func (Dwarf_Func * func, void * arg)
1495{
1496 dwarf_query * q = static_cast<dwarf_query *>(arg);
1497 assert (!q->has_statement_num);
bb788f9f 1498
7e1279ea
FCE
1499 try
1500 {
1501 // XXX: implement
1502 if (q->has_callees)
1503 throw semantic_error ("incomplete: do not know how to interpret .callees",
1504 q->base_probe->tok);
1505
1506 if (q->has_label)
1507 throw semantic_error ("incomplete: do not know how to interpret .label",
1508 q->base_probe->tok);
1509
1510 q->dw.focus_on_function (func);
1511
1512 if (q->dw.func_is_inline ()
1513 && (((q->has_statement_str || q->has_function_str)
1514 && q->dw.function_name_matches(q->function))
1515 || q->has_function_num))
1516 {
1517 if (q->sess.verbose)
1518 clog << "checking instances of inline " << q->dw.function_name << endl;
1519 q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg);
1520 }
39bcd429 1521 else
7e1279ea
FCE
1522 {
1523 bool record_this_function = false;
1524
1525 if ((q->has_statement_str || q->has_function_str)
1526 && q->dw.function_name_matches(q->function))
1527 {
1528 record_this_function = true;
1529 }
1530 else if (q->has_function_num)
1531 {
1532 Dwarf_Addr query_addr = q->function_num_val;
1533
1534 if (q->has_module)
1535 query_addr = q->dw.module_address_to_global(query_addr);
1536
1537 Dwarf_Die d;
1538 q->dw.function_die (&d);
1539
1540 if (q->dw.die_has_pc (&d, query_addr))
1541 record_this_function = true;
1542 }
1543
1544 if (record_this_function)
1545 {
1546 if (q->sess.verbose)
1547 clog << "selected function " << q->dw.function_name << endl;
1548
1549 Dwarf_Addr entrypc;
1550 if (q->dw.function_entrypc (&entrypc))
1551 {
1552 func_info func;
1553 q->dw.function_die (&func.die);
1554 func.name = q->dw.function_name;
4cd232e4
GH
1555 q->dw.function_file (&func.decl_file);
1556 q->dw.function_line (&func.decl_line);
7e1279ea
FCE
1557 q->filtered_functions[entrypc] = func;
1558 }
1559 }
1560 }
39bcd429 1561 return DWARF_CB_OK;
bd2b1e68 1562 }
39bcd429 1563 catch (const semantic_error& e)
bd2b1e68 1564 {
39bcd429
FCE
1565 q->sess.print_error (e);
1566 return DWARF_CB_ABORT;
bd2b1e68 1567 }
bd2b1e68
GH
1568}
1569
1570static int
1571query_cu (Dwarf_Die * cudie, void * arg)
1572{
20c6c071 1573 dwarf_query * q = static_cast<dwarf_query *>(arg);
7a053d3b 1574
39bcd429 1575 try
bd2b1e68 1576 {
7e1279ea 1577 q->dw.focus_on_cu (cudie);
b5d77020
FCE
1578
1579 if (false && q->sess.verbose)
1580 clog << "focused on CU '" << q->dw.cu_name
1581 << "', in module '" << q->dw.module_name << "'" << endl;
d9b516ca 1582
7e1279ea
FCE
1583 if (q->has_statement_str || q->has_function_str || q->has_function_num)
1584 {
1585 q->filtered_srcfiles.clear();
1586 q->filtered_functions.clear();
1587 q->filtered_inlines.clear();
1588
1589 // In this path, we find "abstract functions", record
1590 // information about them, and then (depending on lineno
1591 // matching) possibly emit one or more of the function's
1592 // associated addresses. Unfortunately the control of this
1593 // cannot easily be turned inside out.
1594
1595 if ((q->has_statement_str || q->has_function_str)
1596 && (q->spec_type != function_alone))
1597 {
1598 // If we have a pattern string with a filename, we need
1599 // to elaborate the srcfile mask in question first.
1600 q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
1601
1602 // If we have a file pattern and *no* srcfile matches, there's
1603 // no need to look further into this CU, so skip.
1604 if (q->filtered_srcfiles.empty())
1605 return DWARF_CB_OK;
1606 }
1607
1608 // Pick up [entrypc, name, DIE] tuples for all the functions
1609 // matching the query, and fill in the prologue endings of them
1610 // all in a single pass.
1611 q->dw.iterate_over_functions (query_dwarf_func, q);
1612 q->dw.resolve_prologue_endings (q->filtered_functions);
1613
1614 if ((q->has_statement_str || q->has_function_str)
1615 && (q->spec_type == function_file_and_line))
1616 {
1617 // If we have a pattern string with target *line*, we
1618 // have to look at lines in all the matched srcfiles.
1619 for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
1620 i != q->filtered_srcfiles.end(); ++i)
1621 q->dw.iterate_over_srcfile_lines (*i, q->line, query_srcfile_line, q);
1622 }
1623 else
1624 {
1625 // Otherwise, simply probe all resolved functions...
6e95311e 1626 for (map<Dwarf_Addr, func_info>::const_iterator i = q->filtered_functions.begin();
7e1279ea
FCE
1627 i != q->filtered_functions.end(); ++i)
1628 query_func_info (i->first, i->second, q);
1629
1630 // And all inline instances.
6e95311e 1631 for (map<Dwarf_Addr, inline_instance_info>::const_iterator i
7e1279ea
FCE
1632 = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
1633 query_inline_instance_info (i->first, i->second, q);
1634
1635 }
1636 }
39bcd429
FCE
1637 else
1638 {
7e1279ea
FCE
1639 // Otherwise we have a statement number, and we can just
1640 // query it directly within this module.
1641
1642 assert (q->has_statement_num);
1643 Dwarf_Addr query_addr = q->statement_num_val;
1644 if (q->has_module)
1645 query_addr = q->dw.module_address_to_global(query_addr);
1646
6e95311e 1647 query_statement ("", "", -1, query_addr, q);
39bcd429
FCE
1648 }
1649 return DWARF_CB_OK;
bd2b1e68 1650 }
39bcd429 1651 catch (const semantic_error& e)
bd2b1e68 1652 {
39bcd429
FCE
1653 q->sess.print_error (e);
1654 return DWARF_CB_ABORT;
bd2b1e68 1655 }
bd2b1e68
GH
1656}
1657
1658static int
1659query_module (Dwfl_Module *mod __attribute__ ((unused)),
1660 void **userdata __attribute__ ((unused)),
1661 const char *name, Dwarf_Addr base,
bd2b1e68
GH
1662 void *arg __attribute__ ((unused)))
1663{
20c6c071 1664 dwarf_query * q = static_cast<dwarf_query *>(arg);
bd2b1e68 1665
39bcd429 1666 try
bd2b1e68 1667 {
39bcd429 1668 q->dw.focus_on_module(mod);
d9b516ca 1669
39bcd429
FCE
1670 // If we have enough information in the pattern to skip a module and
1671 // the module does not match that information, return early.
d9b516ca 1672
39bcd429
FCE
1673 if (q->has_kernel && !q->dw.module_name_matches(TOK_KERNEL))
1674 return DWARF_CB_OK;
d9b516ca 1675
39bcd429
FCE
1676 if (q->has_module && !q->dw.module_name_matches(q->module_val))
1677 return DWARF_CB_OK;
b5d77020
FCE
1678
1679 if (q->sess.verbose)
d9b516ca
RM
1680 clog << "focused on module '" << q->dw.module_name
1681 << "' = [" << hex << q->dw.module_start
1682 << "-" << q->dw.module_end
c0de7a8d 1683 << ", bias " << q->dw.module_bias << "]" << dec << endl;
b5d77020 1684
39bcd429
FCE
1685 if (q->has_function_num || q->has_statement_num)
1686 {
1687 // If we have module("foo").function(0xbeef) or
1688 // module("foo").statement(0xbeef), the address is relative
1689 // to the start of the module, so we seek the function
1690 // number plus the module's bias.
7e1279ea 1691
39bcd429
FCE
1692 Dwarf_Addr addr;
1693 if (q->has_function_num)
1694 addr = q->function_num_val;
1695 else
1696 addr = q->statement_num_val;
d9b516ca 1697
7e1279ea
FCE
1698 // NB: We should not have kernel.* here; global addresses
1699 // should have bypassed query_module in dwarf_builder::build
1700 // and gone directly to query_cu.
d9b516ca 1701
7e1279ea
FCE
1702 assert (!q->has_kernel);
1703 assert (q->has_module);
1704 q->dw.query_cu_containing_module_address(addr, q);
39bcd429 1705 }
50e0d793 1706 else
39bcd429
FCE
1707 {
1708 // Otherwise if we have a function("foo") or statement("foo")
1709 // specifier, we have to scan over all the CUs looking for
7e1279ea
FCE
1710 // the function(s) in question
1711
39bcd429
FCE
1712 assert(q->has_function_str || q->has_statement_str);
1713 q->dw.iterate_over_cus(&query_cu, q);
d9b516ca 1714
7e1279ea
FCE
1715 // If we just processed the module "kernel", and the user asked for
1716 // the kernel pattern, there's no need to iterate over any further
1717 // modules
1718
1719 if (q->has_kernel && q->dw.module_name_matches(TOK_KERNEL))
1720 return DWARF_CB_ABORT;
1721 }
bb788f9f 1722
39bcd429 1723 return DWARF_CB_OK;
7a053d3b 1724 }
39bcd429 1725 catch (const semantic_error& e)
bd2b1e68 1726 {
39bcd429
FCE
1727 q->sess.print_error (e);
1728 return DWARF_CB_ABORT;
bd2b1e68 1729 }
bd2b1e68
GH
1730}
1731
77de5e9e
GH
1732struct
1733var_expanding_copy_visitor
1734 : public deep_copy_visitor
1735{
77de5e9e
GH
1736 static unsigned tick;
1737
1738 dwarf_query & q;
77de5e9e
GH
1739 Dwarf_Addr addr;
1740
6e95311e
FCE
1741 var_expanding_copy_visitor(dwarf_query & q, Dwarf_Addr a)
1742 : q(q), addr(a)
77de5e9e 1743 {}
d7f3e0c5 1744 void visit_target_symbol (target_symbol* e);
77de5e9e
GH
1745};
1746
1747
1748unsigned var_expanding_copy_visitor::tick = 0;
1749
1750
1751void
d7f3e0c5 1752var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
77de5e9e 1753{
d7f3e0c5 1754 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
d9b516ca 1755
d7f3e0c5 1756 if (is_active_lvalue(e))
77de5e9e 1757 {
d7f3e0c5
GH
1758 throw semantic_error("read-only special variable "
1759 + e->base_name + " used as lvalue", e->tok);
77de5e9e 1760 }
d9b516ca 1761
d7f3e0c5
GH
1762 string fname = "get_" + e->base_name.substr(1) + "_" + lex_cast<string>(tick++);
1763
1764 // synthesize a function
1765 functiondecl *fdecl = new functiondecl;
1766 embeddedcode *ec = new embeddedcode;
5e309481 1767 ec->tok = e->tok;
66d284f4 1768 try
6e95311e
FCE
1769 {
1770 ec->code = q.dw.literal_stmt_for_local(addr,
66d284f4
FCE
1771 e->base_name.substr(1),
1772 e->components,
1773 fdecl->type);
1774 }
1775 catch (const semantic_error& er)
1776 {
1777 semantic_error er2 (er);
1778 er2.tok1 = e->tok;
1779 throw er2;
1780 }
d7f3e0c5
GH
1781 fdecl->name = fname;
1782 fdecl->body = ec;
d7f3e0c5 1783 q.sess.functions.push_back(fdecl);
d9b516ca 1784
d7f3e0c5
GH
1785 // synthesize a call
1786 functioncall* n = new functioncall;
1787 n->tok = e->tok;
1788 n->function = fname;
1789 n->referent = NULL;
d9b516ca 1790 provide <functioncall*> (this, n);
77de5e9e
GH
1791}
1792
1793
4cd232e4
GH
1794dwarf_derived_probe::dwarf_derived_probe (string const & funcname,
1795 char const * filename,
1796 int line,
1797 Dwarf_Addr addr,
1798 dwarf_query & q)
a229fcd7 1799 : derived_probe (NULL),
fd6602a0 1800 addr(addr),
a229fcd7 1801 module_bias(q.dw.module_bias),
fd6602a0 1802 has_return (q.has_return)
bd2b1e68 1803{
4cd232e4 1804 string module_name(q.dw.module_name);
df8fadee
FCE
1805 // Lock the kernel module in memory.
1806 if (module_name != TOK_KERNEL)
1807 {
1808 // XXX: There is a race window here, between the time that libdw
1809 // opened up this same file for its relocation duties, and now.
1810 int fd = q.sess.module_fds[module_name];
1811 if (fd == 0)
1812 {
1813 string sys_module = "/sys/module/" + module_name + "/sections/.text";
1814 fd = open (sys_module.c_str(), O_RDONLY);
1815 if (fd < 0)
1816 throw semantic_error ("error opening module refcount-bumping file.");
1817 q.sess.module_fds[module_name] = fd;
1818 }
1819 }
1820
a229fcd7
GH
1821 // first synthesize an "expanded" location
1822 vector<probe_point::component*> comps;
1823 comps.push_back
1824 (module_name == TOK_KERNEL
1825 ? new probe_point::component(TOK_KERNEL)
db520b00 1826 : new probe_point::component(TOK_MODULE, new literal_string(module_name)));
b5d77020 1827
db520b00
FCE
1828 string fn_or_stmt;
1829 if (q.has_function_str || q.has_function_num)
1830 fn_or_stmt = "function";
1831 else
1832 fn_or_stmt = "statement";
a229fcd7 1833
db520b00
FCE
1834 if (q.has_function_str || q.has_statement_str)
1835 {
4cd232e4
GH
1836 string retro_name = funcname;
1837 if (filename && !string (filename).empty())
1838 retro_name += ("@" + string (filename));
1839 if (line != -1)
1840 retro_name += (":" + lex_cast<string> (line));
db520b00
FCE
1841 comps.push_back
1842 (new probe_point::component
1843 (fn_or_stmt, new literal_string (retro_name)));
1844 }
1845 else if (q.has_function_num || q.has_statement_num)
1846 {
1847 Dwarf_Addr retro_addr;
1848 if (q.has_function_num)
1849 retro_addr = q.function_num_val;
1850 else
1851 retro_addr = q.statement_num_val;
1852
1853 comps.push_back (new probe_point::component
1854 (fn_or_stmt,
1855 new literal_number(retro_addr))); // XXX: should be hex if possible
a229fcd7
GH
1856 }
1857
db520b00 1858 if (has_return)
a229fcd7 1859 comps.push_back
db520b00 1860 (new probe_point::component(TOK_RETURN));
d9b516ca 1861
a229fcd7
GH
1862 assert(q.base_probe->locations.size() > 0);
1863 locations.push_back(new probe_point(comps, q.base_probe->locations[0]->tok));
1864
1865 // Now make a local-variable-expanded copy of the probe body
6e95311e 1866 var_expanding_copy_visitor v (q, addr);
77de5e9e
GH
1867 require <block*> (&v, &(this->body), q.base_probe->body);
1868 this->tok = q.base_probe->tok;
bd2b1e68
GH
1869}
1870
7a053d3b 1871void
20c6c071 1872dwarf_derived_probe::register_relative_variants(match_node * root,
bd2b1e68
GH
1873 dwarf_builder * dw)
1874{
1875 // Here we match 2 forms:
1876 //
1877 // .
1878 // .relative(NN)
1879
20c6c071
GH
1880 root->bind(dw);
1881 root->bind_num(TOK_RELATIVE)->bind(dw);
bd2b1e68
GH
1882}
1883
7a053d3b 1884void
20c6c071 1885dwarf_derived_probe::register_statement_variants(match_node * root,
bd2b1e68
GH
1886 dwarf_builder * dw)
1887{
1888 // Here we match 3 forms:
1889 //
1890 // .
1891 // .return
1892 // .label("foo")
7a053d3b 1893
bd2b1e68 1894 register_relative_variants(root, dw);
20c6c071 1895 register_relative_variants(root->bind_str(TOK_LABEL), dw);
bd2b1e68
GH
1896}
1897
7a053d3b 1898void
fd6602a0 1899dwarf_derived_probe::register_function_variants(match_node * root,
bd2b1e68
GH
1900 dwarf_builder * dw)
1901{
a229fcd7 1902 // Here we match 4 forms:
bd2b1e68
GH
1903 //
1904 // .
fd6602a0 1905 // .return
bd2b1e68
GH
1906 // .callees
1907 // .callees(N)
1908 //
1909 // The last form permits N-level callee resolving without any
1910 // recursive .callees.callees.callees... pattern-matching on our part.
1911
fd6602a0
FCE
1912 root->bind(dw);
1913 root->bind(TOK_RETURN)->bind(dw);
1914 root->bind(TOK_CALLEES)->bind(dw);
1915 root->bind_num(TOK_CALLEES)->bind(dw);
bd2b1e68
GH
1916}
1917
7a053d3b 1918void
20c6c071 1919dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
bd2b1e68
GH
1920 dwarf_builder * dw)
1921{
1922 // Here we match 4 forms:
1923 //
1924 // .function("foo")
1925 // .function(0xdeadbeef)
1926 // .statement("foo")
1927 // .statement(0xdeadbeef)
1928
fd6602a0
FCE
1929 register_function_variants(root->bind_str(TOK_FUNCTION), dw);
1930 register_function_variants(root->bind_num(TOK_FUNCTION), dw);
20c6c071
GH
1931 register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
1932 register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
bd2b1e68
GH
1933}
1934
1935void
20c6c071 1936dwarf_derived_probe::register_patterns(match_node * root)
bd2b1e68
GH
1937{
1938 dwarf_builder *dw = new dwarf_builder();
1939
1940 // Here we match 3 forms:
1941 //
1942 // .kernel
1943 // .module("foo")
1944 // .process("foo")
1945
20c6c071 1946 register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
fe3d01fa 1947 // XXX: may need to disable these for 2005-08 release
20c6c071
GH
1948 register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
1949 register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
bd2b1e68
GH
1950}
1951
7a053d3b 1952static string
ec4373ff 1953probe_entry_function_name(unsigned probenum)
b55bc428 1954{
ec4373ff
GH
1955 return "dwarf_kprobe_" + lex_cast<string>(probenum) + "_enter";
1956}
1957
7a053d3b 1958static string
20c6c071 1959probe_entry_struct_kprobe_name(unsigned probenum)
ec4373ff 1960{
20c6c071 1961 return "dwarf_kprobe_" + lex_cast<string>(probenum);
ec4373ff
GH
1962}
1963
7a053d3b 1964void
20c6c071 1965dwarf_derived_probe::emit_registrations (translator_output* o, unsigned probenum)
ec4373ff 1966{
59ff2773
FCE
1967 if (has_return)
1968 {
1969 o->newline() << probe_entry_struct_kprobe_name(probenum)
db520b00 1970 << ".kp.addr = (void *) 0x" << hex << addr << ";" << dec;
59ff2773
FCE
1971 o->newline() << "rc = register_kretprobe (&"
1972 << probe_entry_struct_kprobe_name(probenum)
1973 << ");";
ec4373ff 1974 }
20c6c071 1975 else
bd2b1e68 1976 {
59ff2773 1977 o->newline() << probe_entry_struct_kprobe_name(probenum)
db520b00 1978 << ".addr = (void *) 0x" << hex << addr << ";" << dec;
7a053d3b 1979 o->newline() << "rc = register_kprobe (&"
59ff2773
FCE
1980 << probe_entry_struct_kprobe_name(probenum)
1981 << ");";
bd2b1e68 1982 }
b55bc428
FCE
1983}
1984
7a053d3b 1985void
ec4373ff 1986dwarf_derived_probe::emit_deregistrations (translator_output* o, unsigned probenum)
b55bc428 1987{
fd6602a0
FCE
1988 if (has_return)
1989 o->newline() << "unregister_kretprobe (& "
1990 << probe_entry_struct_kprobe_name(probenum)
1991 << ");";
1992 else
1993 o->newline() << "unregister_kprobe (& "
1994 << probe_entry_struct_kprobe_name(probenum)
1995 << ");";
ec4373ff
GH
1996}
1997
7a053d3b 1998void
ec4373ff
GH
1999dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum)
2000{
499cf740
FCE
2001 static unsigned already_emitted_fault_handler = 0;
2002
2003 if (! already_emitted_fault_handler)
2004 {
2005 o->newline() << "int stap_kprobe_fault_handler (struct kprobe* kp, "
2006 << "struct pt_regs* regs, int trapnr) {";
2007 o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
2008 o->newline() << "printk (KERN_ERR \"systemtap probe fault\\n\");";
2009 o->newline() << "printk (KERN_ERR \"cpu %d, probe %s, near %s\\n\", ";
2010 o->newline(1) << "smp_processor_id(), ";
2011 o->newline() << "c->probe_point ? c->probe_point : \"unknown\", ";
2012 o->newline() << "c->last_stmt ? c->last_stmt : \"unknown\");";
2013 o->newline() << "c->last_error = \"probe faulted\";";
2014 o->newline(-1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
2015
2016 o->newline() << "return 0;"; // defer to kernel fault handler
2017 // NB: We might prefer to use "return 1" instead, to consider
2018 // the fault "handled". But we may get into an infinite loop
2019 // of traps if the faulting instruction is simply restarted.
2020
2021 o->newline(-1) << "}";
2022 already_emitted_fault_handler ++;
2023 }
2024
7a053d3b 2025 // Construct a single entry function, and a struct kprobe pointing into
20c6c071 2026 // the entry function. The entry function will call the probe function.
20c6c071 2027 o->newline();
3d49c615 2028 o->newline() << "static int ";
9e6edd10
FCE
2029 o->newline() << probe_entry_function_name(probenum) << " (";
2030 if (has_return)
2031 o->line() << "struct kretprobe_instance *_ignored";
2032 else
2033 o->line() << "struct kprobe *_ignored";
2034 o->line() << ", struct pt_regs *regs) {";
3d49c615 2035 o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
cc9ee605
FCE
2036 o->newline() << "const char* probe_point = "
2037 << lex_cast_qstring(*locations[0]) << ";";
bfb3d2d2
FCE
2038
2039 // A precondition for running a probe handler is that we're in RUNNING
2040 // state (not ERROR), and that no one else is already using this context.
2041 o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
3d49c615 2042 o->newline(1) << "return 0;";
cc9ee605 2043 o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
499cf740 2044 o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
cc9ee605 2045 << "c->probe_point, probe_point);";
bfb3d2d2 2046 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
3d49c615 2047 o->newline() << "return 0;";
bfb3d2d2
FCE
2048 o->newline(-1) << "}";
2049 o->newline();
2050
5e309481 2051 o->newline() << "c->last_error = 0;";
cc9ee605 2052 o->newline() << "c->probe_point = probe_point;";
ec4373ff 2053 o->newline() << "c->nesting = 0;";
3d49c615 2054 o->newline() << "c->regs = regs;";
5e309481
FCE
2055 o->newline() << "c->actioncount = 0;";
2056
ec4373ff
GH
2057 // NB: locals are initialized by probe function itself
2058 o->newline() << "probe_" << probenum << " (c);";
bfb3d2d2 2059
bb788f9f
FCE
2060 o->newline() << "if (c->last_error && c->last_error[0]) {";
2061 o->newline(1) << "_stp_error (\"%s near %s\", c->last_error, c->last_stmt);";
5e309481 2062 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
bfb3d2d2 2063 o->newline(-1) << "}";
bb788f9f 2064
cc9ee605 2065 o->newline() << "atomic_dec (& c->busy);";
3d49c615 2066 o->newline() << "return 0;";
ec4373ff
GH
2067 o->newline(-1) << "}" << endl;
2068
20c6c071 2069 o->newline();
fd6602a0
FCE
2070 if (has_return)
2071 {
2072 o->newline() << "static struct kretprobe "
2073 << probe_entry_struct_kprobe_name(probenum)
2074 << "= {";
db520b00 2075 o->newline(1) << ".kp.addr = 0," ;
bb788f9f
FCE
2076 o->newline() << ".handler = &"
2077 << probe_entry_function_name(probenum) << ",";
2c89cb8b
FCE
2078 // XXX: pending PR 1289
2079 // o->newline() << ".kp.fault_handler = &stap_kprobe_fault_handler,";
bb788f9f 2080 o->newline() << ".maxactive = 1";
fd6602a0
FCE
2081 o->newline(-1) << "};";
2082 }
2083 else
2084 {
2085 o->newline() << "static struct kprobe "
2086 << probe_entry_struct_kprobe_name(probenum)
2087 << "= {";
db520b00 2088 o->newline(1) << ".addr = 0," ;
2c89cb8b
FCE
2089 // XXX: pending PR 1289
2090 // o->newline() << ".fault_handler = &stap_kprobe_fault_handler,";
fd6602a0
FCE
2091 o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum);
2092 o->newline(-1) << "};";
2093 }
20c6c071
GH
2094 o->newline();
2095}
ec4373ff 2096
20c6c071
GH
2097
2098void
5227f1ea 2099dwarf_builder::build(systemtap_session & sess,
7a053d3b 2100 probe * base,
20c6c071
GH
2101 probe_point * location,
2102 std::map<std::string, literal *> const & parameters,
2103 vector<probe *> & results_to_expand_further,
2104 vector<derived_probe *> & finished_results)
2105{
2106
5227f1ea
GH
2107 dwflpp dw(sess);
2108 dwarf_query q(sess, base, location, dw, parameters, finished_results);
20c6c071
GH
2109
2110 dw.setup(q.has_kernel || q.has_module);
2111
7e1279ea 2112 if (q.has_kernel && (q.has_function_num || q.has_statement_num))
20c6c071 2113 {
50e0d793
GH
2114 // If we have kernel.function(0xbeef), or
2115 // kernel.statement(0xbeef) the address is global (relative to
2116 // the kernel) and we can seek directly to the module and cudie
2117 // in question.
d9b516ca
RM
2118 Dwarf_Addr a = (q.has_function_num
2119 ? q.function_num_val
50e0d793
GH
2120 : q.statement_num_val);
2121 dw.focus_on_module_containing_global_address(a);
7e1279ea 2122 dw.query_cu_containing_global_address(a, &q);
20c6c071 2123 }
7a053d3b 2124 else
20c6c071
GH
2125 {
2126 // Otherwise we have module("foo"), kernel.statement("foo"), or
2127 // kernel.function("foo"); in these cases we need to scan all
2128 // the modules.
7a053d3b 2129 assert((q.has_kernel && q.has_function_str) ||
20c6c071
GH
2130 (q.has_kernel && q.has_statement_str) ||
2131 (q.has_module));
2132 dw.iterate_over_modules(&query_module, &q);
2133 }
b55bc428
FCE
2134}
2135
2136
98afd80e
FCE
2137
2138// ------------------------------------------------------------------------
2139// timer derived probes
2140// ------------------------------------------------------------------------
2141
2142
2143struct timer_derived_probe: public derived_probe
2144{
2145 int64_t interval, randomize;
2146
2147 timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r);
2148
2149 virtual void emit_registrations (translator_output * o, unsigned i);
2150 virtual void emit_deregistrations (translator_output * o, unsigned i);
2151 virtual void emit_probe_entries (translator_output * o, unsigned i);
2152};
2153
2154
2155timer_derived_probe::timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r):
2156 derived_probe (p, l), interval (i), randomize (r)
2157{
2158 if (interval <= 0 || interval > 1000000) // make i and r fit into plain ints
2159 throw semantic_error ("invalid interval for jiffies timer");
2160 // randomize = 0 means no randomization
2161 if (randomize < 0 || randomize > interval)
2162 throw semantic_error ("invalid randomize for jiffies timer");
2163
2164 if (locations.size() != 1)
2165 throw semantic_error ("expect single probe point");
2166 // so we don't have to loop over them in the other functions
2167}
2168
2169
2170void
2171timer_derived_probe::emit_registrations (translator_output* o, unsigned j)
2172{
2173 o->newline() << "init_timer (& timer_" << j << ");";
2174 o->newline() << "timer_" << j << ".expires = jiffies + " << interval << ";";
2175 o->newline() << "timer_" << j << ".function = & enter_" << j << ";";
2176 o->newline() << "add_timer (& timer_" << j << ");";
2177}
2178
2179
2180void
2181timer_derived_probe::emit_deregistrations (translator_output* o, unsigned j)
2182{
2183 o->newline() << "del_timer_sync (& timer_" << j << ");";
2184}
2185
2186
2187void
2188timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
2189{
2190 o->newline() << "static struct timer_list timer_" << j << ";";
2191
2192 o->newline() << "void enter_" << j << " (unsigned long val) {";
2193 o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
cc9ee605
FCE
2194 o->newline() << "const char* probe_point = "
2195 << lex_cast_qstring(*locations[0]) << ";";
98afd80e
FCE
2196 o->newline() << "(void) val;";
2197
2198 // A precondition for running a probe handler is that we're in
2199 // RUNNING state (not ERROR), and that no one else is already using
2200 // this context.
2201 o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
2202 o->newline(1) << "return;";
2203
cc9ee605 2204 o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
499cf740 2205 o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\\n\", "
cc9ee605 2206 << "c->probe_point, probe_point);";
98afd80e
FCE
2207 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
2208 o->newline() << "return;";
2209 o->newline(-1) << "}";
2210 o->newline();
2211
2212 o->newline() << "mod_timer (& timer_" << j << ", "
2213 << "jiffies + " << interval;
2214 if (randomize)
2215 o->line() << " + _stp_random_pm(" << randomize << ")";
2216 o->line() << ");";
2217
cc9ee605 2218 o->newline() << "c->probe_point = probe_point;";
5e309481 2219 o->newline() << "c->last_error = 0;";
98afd80e 2220 o->newline() << "c->nesting = 0;";
cc9ee605 2221 o->newline() << "if (in_interrupt())";
98afd80e
FCE
2222 o->newline(1) << "c->regs = 0;";
2223 o->newline(-1) << "else";
2224 o->newline(1) << "c->regs = task_pt_regs (current);";
2225 o->indent(-1);
5e309481 2226 o->newline() << "c->actioncount = 0;";
98afd80e
FCE
2227
2228 // NB: locals are initialized by probe function itself
2229 o->newline() << "probe_" << j << " (c);";
2230
bb788f9f
FCE
2231 o->newline() << "if (c->last_error && c->last_error[0]) {";
2232 o->newline(1) << "_stp_error (\"%s near %s\", c->last_error, c->last_stmt);";
5e309481 2233 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
98afd80e
FCE
2234 o->newline(-1) << "}";
2235
cc9ee605 2236 o->newline() << "atomic_dec (&c->busy);";
98afd80e
FCE
2237 o->newline(-1) << "}" << endl;
2238}
2239
2240
2241struct timer_builder: public derived_probe_builder
2242{
2243 timer_builder() {}
2244 virtual void build(systemtap_session & sess,
2245 probe * base,
2246 probe_point * location,
2247 std::map<std::string, literal *> const & parameters,
2248 vector<probe *> &,
2249 vector<derived_probe *> & finished_results)
2250 {
2251 int64_t jn, rn;
2252 bool jn_p, rn_p;
2253
2254 jn_p = get_param (parameters, "jiffies", jn);
2255 rn_p = get_param (parameters, "randomize", rn);
2256
2257 finished_results.push_back(new timer_derived_probe(base, location,
2258 jn, rn_p ? rn : 0));
2259 }
2260};
2261
2262
2263
b55bc428 2264// ------------------------------------------------------------------------
bd2b1e68 2265// Standard tapset registry.
b55bc428
FCE
2266// ------------------------------------------------------------------------
2267
7a053d3b 2268void
f8220a7b 2269register_standard_tapsets(systemtap_session & s)
b55bc428 2270{
bd2b1e68 2271 // Rudimentary binders for begin and end targets
f8220a7b
GH
2272 s.pattern_root->bind("begin")->bind(new be_builder(true));
2273 s.pattern_root->bind("end")->bind(new be_builder(false));
98afd80e
FCE
2274 s.pattern_root->bind("timer")->bind_num("jiffies")->bind(new timer_builder());
2275 s.pattern_root->bind("timer")->bind_num("jiffies")->bind_num("randomize")->bind(new timer_builder());
b98a8d73 2276
14d0763f 2277 // kernel/module parts
f8220a7b 2278 dwarf_derived_probe::register_patterns(s.pattern_root);
b55bc428 2279}
This page took 0.309529 seconds and 5 git commands to generate.