]> sourceware.org Git - systemtap.git/blame - tapsets.cxx
.
[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>
bd2b1e68
GH
22
23extern "C" {
24#include <elfutils/libdwfl.h>
7a053d3b 25#include <elfutils/libdw.h>
77de5e9e
GH
26#include <dwarf.h>
27#include <elf.h>
28#include <obstack.h>
29#include "loc2c.h"
bd2b1e68 30}
77de5e9e 31
bd2b1e68 32#include <fnmatch.h>
56e12059
FCE
33
34using namespace std;
35
b55bc428
FCE
36// ------------------------------------------------------------------------
37// begin/end probes are run right during registration / deregistration
56e12059
FCE
38// ------------------------------------------------------------------------
39
b55bc428
FCE
40struct be_derived_probe: public derived_probe
41{
42 bool begin;
43 be_derived_probe (probe* p, bool b): derived_probe (p), begin (b) {}
44 be_derived_probe (probe* p, probe_point* l, bool b):
45 derived_probe (p, l), begin (b) {}
56e12059 46
b55bc428
FCE
47 void emit_registrations (translator_output* o, unsigned i);
48 void emit_deregistrations (translator_output* o, unsigned i);
49 void emit_probe_entries (translator_output* o, unsigned i);
50};
51
52struct
7a053d3b 53be_builder
b55bc428
FCE
54 : public derived_probe_builder
55{
56 bool begin;
57 be_builder(bool b) : begin(b) {}
5227f1ea 58 virtual void build(systemtap_session & sess,
7a053d3b 59 probe * base,
20c6c071
GH
60 probe_point * location,
61 std::map<std::string, literal *> const & parameters,
62 vector<probe *> & results_to_expand_further,
63 vector<derived_probe *> & finished_results)
b55bc428 64 {
20c6c071 65 finished_results.push_back(new be_derived_probe(base, location, begin));
b55bc428
FCE
66 }
67 virtual ~be_builder() {}
68};
56e12059
FCE
69
70
7a053d3b 71void
56e12059
FCE
72be_derived_probe::emit_registrations (translator_output* o, unsigned j)
73{
74 if (begin)
75 for (unsigned i=0; i<locations.size(); i++)
bfb3d2d2 76 o->newline() << "enter_" << j << "_" << i << " ();";
56e12059
FCE
77}
78
79
7a053d3b 80void
56e12059
FCE
81be_derived_probe::emit_deregistrations (translator_output* o, unsigned j)
82{
bfb3d2d2 83 if (!begin)
56e12059 84 for (unsigned i=0; i<locations.size(); i++)
bfb3d2d2 85 o->newline() << "enter_" << j << "_" << i << " ();";
56e12059
FCE
86}
87
88
89void
90be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
91{
92 for (unsigned i=0; i<locations.size(); i++)
93 {
94 probe_point *l = locations[i];
95 o->newline() << "/* location " << i << ": " << *l << " */";
f4b28491
FCE
96 o->newline() << "static void enter_" << j << "_" << i << " (void);";
97 o->newline() << "void enter_" << j << "_" << i << " () {";
bfb3d2d2 98
7a053d3b 99 // While begin/end probes are executed single-threaded, we
bfb3d2d2
FCE
100 // still code defensively and use a per-cpu context.
101 o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
102
103 // A precondition for running a probe handler is that we're in STARTING
104 // or STOPPING state (not ERROR), and that no one else is already using
105 // this context.
106 o->newline() << "if (atomic_read (&session_state) != ";
107 if (begin) o->line() << "STAP_SESSION_STARTING)";
108 else o->line() << "STAP_SESSION_STOPPING)";
109 o->newline(1) << "return;";
110 o->newline(-1) << "if (c->busy) {";
111 o->newline(1) << "printk (KERN_ERR \"probe reentrancy\");";
112 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
113 o->newline() << "return;";
114 o->newline(-1) << "}";
115 o->newline();
7a053d3b 116
56e12059 117 o->newline() << "c->busy ++;";
bfb3d2d2
FCE
118 o->newline() << "mb ();"; // for smp
119 o->newline() << "c->errorcount = 0;";
56e12059
FCE
120 o->newline() << "c->actioncount = 0;";
121 o->newline() << "c->nesting = 0;";
3d49c615 122 o->newline() << "c->regs = 0;";
bfb3d2d2 123
56e12059
FCE
124 // NB: locals are initialized by probe function itself
125 o->newline() << "probe_" << j << " (c);";
bfb3d2d2
FCE
126
127 // see translate.cxx: visit_functioncall and elsewhere to see all the
128 // possible context indications that a probe exited prematurely
3d49c615
FCE
129 o->newline() << "if (c->errorcount || c->actioncount > MAXACTION"
130 << " || c->nesting+2 >= MAXNESTING) {";
131 o->newline(1) << "printk (KERN_ERR \"probe execution failure (e%d,n%d,a%d)\",";
bfb3d2d2
FCE
132 o->newline(1) << "c->errorcount, c->nesting, c->actioncount);";
133 o->newline(-1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
134 o->newline(-1) << "}";
135
56e12059 136 o->newline() << "c->busy --;";
bfb3d2d2 137 o->newline() << "mb ();";
56e12059
FCE
138 o->newline(-1) << "}" << endl;
139 }
140}
141
142
143// ------------------------------------------------------------------------
bd2b1e68 144// Dwarf derived probes.
b55bc428 145// ------------------------------------------------------------------------
bd2b1e68 146
c239d28c
GH
147static string TOK_PROCESS("process");
148static string TOK_KERNEL("kernel");
149static string TOK_MODULE("module");
150
151static string TOK_FUNCTION("function");
152static string TOK_RETURN("return");
153static string TOK_CALLEES("callees");
154
155static string TOK_STATEMENT("statement");
156static string TOK_LABEL("label");
157static string TOK_RELATIVE("relative");
158
59ff2773
FCE
159
160// XXX: should standardize to these functions throughout translator
161
7a053d3b 162template <typename OUT, typename IN> inline OUT
77de5e9e
GH
163lex_cast(IN const & in)
164{
165 stringstream ss;
166 OUT out;
167 if (!(ss << in && ss >> out))
168 throw runtime_error("bad lexical cast");
169 return out;
170}
171
59ff2773
FCE
172template <typename OUT, typename IN> inline OUT
173lex_cast_hex(IN const & in)
174{
175 stringstream ss;
176 OUT out;
177 if (!(ss << hex << showbase << in && ss >> out))
178 throw runtime_error("bad lexical cast");
179 return out;
180}
181
182
183
bd2b1e68
GH
184// Helper for dealing with selected portions of libdwfl in a more readable
185// fashion, and with specific cleanup / checking / logging options.
186
91eefb1c
GH
187static const char *
188dwarf_diename_integrate (Dwarf_Die *die)
189{
190 Dwarf_Attribute attr_mem;
191 return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
192}
193
bd2b1e68
GH
194struct
195dwflpp
196{
5227f1ea 197 systemtap_session & sess;
bd2b1e68
GH
198 Dwfl * dwfl;
199
200 // These are "current" values we focus on.
201 Dwfl_Module * module;
202 Dwarf * module_dwarf;
203 Dwarf_Addr module_bias;
50e0d793
GH
204
205 // These describe the current module's PC address range
206 Dwarf_Addr module_start;
207 Dwarf_Addr module_end;
208
bd2b1e68
GH
209 Dwarf_Die * cu;
210 Dwarf_Func * function;
211
212 string module_name;
213 string cu_name;
214 string function_name;
215
50e0d793 216
7a053d3b 217 string const default_name(char const * in,
bd2b1e68
GH
218 char const * type)
219 {
7a053d3b 220 if (in)
bd2b1e68 221 return in;
24cb178f 222 if (false && sess.verbose)
bd2b1e68 223 clog << "WARNING: no name found for " << type << endl;
a229fcd7 224 return string("");
bd2b1e68
GH
225 }
226
50e0d793 227
5227f1ea
GH
228 void get_module_dwarf()
229 {
230 if (!module_dwarf)
231 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
a229fcd7 232 if (module_dwarf == NULL && sess.verbose)
d9b516ca 233 clog << "WARNING: dwfl_module_getdwarf() : "
a229fcd7 234 << dwfl_errmsg (dwfl_errno ()) << endl;
5227f1ea
GH
235 }
236
50e0d793 237
bd2b1e68
GH
238 void focus_on_module(Dwfl_Module * m)
239 {
240 assert(m);
241 module = m;
7a053d3b 242 module_name = default_name(dwfl_module_info(module, NULL,
50e0d793 243 &module_start, &module_end,
bd2b1e68
GH
244 NULL, NULL,
245 NULL, NULL),
246 "module");
50e0d793
GH
247
248 // Reset existing pointers and names
249
250 module_dwarf = NULL;
251
a229fcd7 252 cu_name.clear();
50e0d793
GH
253 cu = NULL;
254
a229fcd7 255 function_name.clear();
50e0d793 256 function = NULL;
bd2b1e68
GH
257 }
258
50e0d793 259
bd2b1e68
GH
260 void focus_on_cu(Dwarf_Die * c)
261 {
262 assert(c);
50e0d793
GH
263 assert(module);
264
bd2b1e68 265 cu = c;
50e0d793
GH
266 cu_name = default_name(dwarf_diename(c), "CU");
267
268 // Reset existing pointers and names
a229fcd7 269 function_name.clear();
50e0d793 270 function = NULL;
bd2b1e68
GH
271 }
272
50e0d793 273
bd2b1e68
GH
274 void focus_on_function(Dwarf_Func * f)
275 {
276 assert(f);
50e0d793
GH
277 assert(module);
278 assert(cu);
279
bd2b1e68 280 function = f;
7a053d3b 281 function_name = default_name(dwarf_func_name(function),
bd2b1e68 282 "function");
bd2b1e68
GH
283 }
284
50e0d793 285
bd2b1e68
GH
286 void focus_on_module_containing_global_address(Dwarf_Addr a)
287 {
288 assert(dwfl);
50e0d793 289 cu = NULL;
24cb178f 290 if (false && sess.verbose)
bd2b1e68
GH
291 clog << "focusing on module containing global addr " << a << endl;
292 focus_on_module(dwfl_addrmodule(dwfl, a));
293 }
294
50e0d793
GH
295
296 void focus_on_cu_containing_global_address(Dwarf_Addr a)
bd2b1e68 297 {
bd2b1e68 298 Dwarf_Addr bias;
50e0d793 299 assert(dwfl);
5227f1ea 300 get_module_dwarf();
aab2b35f 301 if (false && sess.verbose)
50e0d793 302 clog << "focusing on cu containing global addr " << a << endl;
bd2b1e68
GH
303 focus_on_cu(dwfl_module_addrdie(module, a, &bias));
304 assert(bias == module_bias);
305 }
306
50e0d793
GH
307
308 void focus_on_cu_containing_module_address(Dwarf_Addr a)
bd2b1e68 309 {
50e0d793 310 focus_on_cu_containing_global_address(module_address_to_global(a));
bd2b1e68
GH
311 }
312
50e0d793 313
bd2b1e68
GH
314 Dwarf_Addr module_address_to_global(Dwarf_Addr a)
315 {
50e0d793 316 assert(dwfl);
bd2b1e68 317 assert(module);
5227f1ea 318 get_module_dwarf();
c239d28c
GH
319 if (module_name == TOK_KERNEL)
320 return a;
321
db520b00
FCE
322 if (false && sess.verbose)
323 clog << "module addr " << hex << a
324 << " + module start " << module_start
325 << " -> global addr " << (a + module_start) << dec << endl;
50e0d793 326 return a + module_start;
bd2b1e68
GH
327 }
328
50e0d793 329
bd2b1e68
GH
330 Dwarf_Addr global_address_to_module(Dwarf_Addr a)
331 {
332 assert(module);
5227f1ea 333 get_module_dwarf();
db520b00
FCE
334 if (false && sess.verbose)
335 clog << "global addr " << a
336 << " - module start " << hex << module_start
337 << " -> module addr " << (a - module_start) << dec << endl;
bd2b1e68
GH
338 return a - module_bias;
339 }
340
341
342 bool module_name_matches(string pattern)
343 {
344 assert(module);
345 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
24cb178f 346 if (t && sess.verbose)
bd2b1e68 347 clog << "pattern '" << pattern << "' "
24cb178f 348 << "matches "
bd2b1e68
GH
349 << "module '" << module_name << "'" << endl;
350 return t;
351 }
352
50e0d793 353
bd2b1e68
GH
354 bool function_name_matches(string pattern)
355 {
356 assert(function);
357 bool t = (fnmatch(pattern.c_str(), function_name.c_str(), 0) == 0);
24cb178f 358 if (t && sess.verbose)
bd2b1e68 359 clog << "pattern '" << pattern << "' "
24cb178f 360 << "matches "
bd2b1e68
GH
361 << "function '" << function_name << "'" << endl;
362 return t;
363 }
364
50e0d793 365
bd2b1e68
GH
366 bool cu_name_matches(string pattern)
367 {
368 assert(cu);
369 bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
24cb178f 370 if (t && sess.verbose)
bd2b1e68 371 clog << "pattern '" << pattern << "' "
24cb178f 372 << "matches "
bd2b1e68
GH
373 << "CU '" << cu_name << "'" << endl;
374 return t;
375 }
376
50e0d793 377
d8067b24 378 void dwflpp_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
bd2b1e68 379 {
d8067b24
FCE
380 string msg = "dwfl failure (" + desc + "): ";
381 if (rc < 0) msg += dwfl_errmsg (rc);
382 else if (rc > 0) msg += strerror (rc);
bd2b1e68 383 if (rc != 0)
d8067b24 384 throw semantic_error (msg);
bd2b1e68
GH
385 }
386
50e0d793 387
5227f1ea 388 dwflpp(systemtap_session & sess)
bd2b1e68 389 :
5227f1ea 390 sess(sess),
bd2b1e68
GH
391 dwfl(NULL),
392 module(NULL),
393 module_dwarf(NULL),
394 module_bias(0),
50e0d793
GH
395 module_start(0),
396 module_end(0),
bd2b1e68
GH
397 cu(NULL),
398 function(NULL)
399 {}
7a053d3b 400
50e0d793 401
bd2b1e68
GH
402 void setup(bool kernel)
403 {
b5d77020
FCE
404 // XXX: this is where the session -R parameter could come in
405 static char* debuginfo_path = "-:.debug:/usr/lib/debug";
406
bd2b1e68
GH
407 static const Dwfl_Callbacks proc_callbacks =
408 {
409 dwfl_linux_proc_find_elf,
410 dwfl_standard_find_debuginfo,
411 NULL,
b5d77020 412 & debuginfo_path
bd2b1e68 413 };
7a053d3b 414
bd2b1e68
GH
415 static const Dwfl_Callbacks kernel_callbacks =
416 {
417 dwfl_linux_kernel_find_elf,
418 dwfl_standard_find_debuginfo,
419 dwfl_linux_kernel_module_section_address,
b5d77020 420 & debuginfo_path
bd2b1e68
GH
421 };
422
423 if (kernel)
424 {
425 dwfl = dwfl_begin(&kernel_callbacks);
426 if (!dwfl)
427 throw semantic_error("cannot open dwfl");
428 dwfl_report_begin(dwfl);
d8067b24
FCE
429 // XXX: if we have only kernel.* probe points, we shouldn't waste time
430 // looking for module debug-info (and vice versa).
431 dwflpp_assert("find kernel debug-info", dwfl_linux_kernel_report_kernel(dwfl));
432 dwflpp_assert("find modules debug-info", dwfl_linux_kernel_report_modules(dwfl));
bd2b1e68
GH
433 }
434 else
435 {
436 dwfl = dwfl_begin(&proc_callbacks);
437 dwfl_report_begin(dwfl);
438 if (!dwfl)
439 throw semantic_error("cannot open dwfl");
440 // XXX: Find pids or processes, do userspace stuff.
441 }
442
377b8831 443 dwflpp_assert("report_end", dwfl_report_end(dwfl, NULL, NULL));
bd2b1e68
GH
444 }
445
446 void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
447 const char *, Dwarf_Addr,
77de5e9e 448 void *),
bd2b1e68
GH
449 void * data)
450 {
bd2b1e68
GH
451 ptrdiff_t off = 0;
452 do
453 {
77de5e9e 454 off = dwfl_getmodules (dwfl, callback, data, off);
bd2b1e68
GH
455 }
456 while (off > 0);
377b8831 457 dwflpp_assert("getdwarf", off);
bd2b1e68
GH
458 }
459
7a053d3b 460 void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
bd2b1e68
GH
461 void * data)
462 {
5227f1ea
GH
463 get_module_dwarf();
464
bd2b1e68
GH
465 if (!module_dwarf)
466 {
467 cerr << "WARNING: no dwarf info found for module " << module_name << endl;
468 return;
469 }
470
bd2b1e68
GH
471 Dwarf *dw = module_dwarf;
472 Dwarf_Off off = 0;
473 size_t cuhl;
474 Dwarf_Off noff;
475 while (dwarf_nextcu(dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
7a053d3b 476 {
bd2b1e68
GH
477 Dwarf_Die die_mem;
478 Dwarf_Die *die;
479 die = dwarf_offdie(dw, off + cuhl, &die_mem);
480 if (callback(die, data) != DWARF_CB_OK)
481 break;
482 off = noff;
483 }
484 }
485
486 void iterate_over_functions(int (* callback)(Dwarf_Func * func, void * arg),
487 void * data)
488 {
489 assert(module);
490 assert(cu);
bd2b1e68
GH
491 dwarf_getfuncs(cu, callback, data, 0);
492 }
493
494 bool function_entrypc(Dwarf_Addr * addr)
495 {
496 return (dwarf_func_entrypc(function, addr) == 0);
497 }
498
499 bool function_includes_global_addr(Dwarf_Addr addr)
500 {
501 assert(module_dwarf);
502 assert(cu);
503 assert(function);
504 Dwarf_Addr lo, hi;
505 if (dwarf_func_lowpc(function, &lo) != 0)
506 {
db520b00 507 if (false && sess.verbose)
bd2b1e68
GH
508 clog << "WARNING: cannot find low PC value for function " << function_name << endl;
509 return false;
510 }
7a053d3b 511
bd2b1e68
GH
512 if (dwarf_func_highpc(function, &hi) != 0)
513 {
db520b00 514 if (false && sess.verbose)
bd2b1e68
GH
515 clog << "WARNING: cannot find high PC value for function " << function_name << endl;
516 return false;
517 }
7a053d3b 518
bd2b1e68 519 bool t = lo <= addr && addr <= hi;
db520b00
FCE
520 if (t && sess.verbose)
521 clog << "function " << function_name << " = [" << hex << lo << "," << hi << "] "
522 << "contains global addr " << addr << dec << endl;
bd2b1e68
GH
523 return t;
524 }
525
bd2b1e68
GH
526
527 Dwarf_Addr global_addr_of_line_in_cu(int line)
528 {
529 Dwarf_Lines * lines;
bd2b1e68 530 Dwarf_Addr addr;
c239d28c
GH
531 size_t nlines;
532 int best_line = -1;
bd2b1e68
GH
533
534 assert(module);
535 assert(cu);
377b8831 536 dwflpp_assert("getsrclines", dwarf_getsrclines(cu, &lines, &nlines));
50e0d793
GH
537
538 for (size_t i = 0; i < nlines; ++i)
539 {
540 int curr_line;
541 Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
d9b516ca 542 dwflpp_assert("lineno", dwarf_lineno (line_rec, &curr_line));
c239d28c
GH
543
544 if (curr_line >= line && (best_line == -1 || curr_line < best_line))
50e0d793 545 {
c239d28c 546 best_line = curr_line;
50e0d793 547 dwflpp_assert("lineaddr", dwarf_lineaddr(line_rec, &addr));
50e0d793
GH
548 }
549 }
d9b516ca 550
c239d28c 551 if (best_line != -1)
d9b516ca 552 {
c239d28c
GH
553 if (sess.verbose)
554 clog << "line " << best_line
555 << " (given query line " << line << ")"
556 << " of CU " << cu_name
db520b00
FCE
557 << " has module address " << hex << addr
558 << " in " << module_name << dec << endl;
c239d28c
GH
559 return module_address_to_global(addr);
560 }
50e0d793 561
5227f1ea 562 if (sess.verbose)
d9b516ca 563 clog << "WARNING: could not find line " << line
50e0d793
GH
564 << " in CU " << cu_name << endl;
565 return 0;
566 }
567
568
569 bool function_prologue_end(Dwarf_Addr * addr)
570 {
50e0d793
GH
571 Dwarf_Lines * lines;
572 size_t nlines;
573
574 assert(addr);
575 dwflpp_assert("getsrclines", dwarf_getsrclines(cu, &lines, &nlines));
576
577
578 // If GCC output the right information we would do this:
579 /*
580
581 for (size_t i = 0; i < nlines; ++i)
582 {
583 bool flag;
584 Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
d9b516ca 585
50e0d793
GH
586 dwflpp_assert("lineprologueend", dwarf_lineprologueend (line_rec, &flag));
587
588 if (sess.verbose)
d9b516ca
RM
589 clog << "checked line record " << i
590 << ", is " << (flag ? "" : " not")
50e0d793
GH
591 << " prologue end" << endl;
592
593 if (flag)
594 {
595 dwflpp_assert("lineaddr", dwarf_lineaddr(line_rec, addr));
596 return true;
597 }
598 }
599 return false;
600 */
601
602 // Since GCC does not output the right information, we do this:
d9b516ca 603
50e0d793
GH
604 Dwarf_Addr entrypc;
605 if (!function_entrypc(&entrypc))
606 return false;
607
608 bool choose_next_line = false;
609
610 for (size_t i = 0; i < nlines; ++i)
611 {
612 Dwarf_Addr line_addr;
613 Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
614 dwflpp_assert("lineaddr", dwarf_lineaddr(line_rec, &line_addr));
615 if (choose_next_line)
616 {
617 *addr = line_addr;
618 if (sess.verbose)
619 clog << "function " << function_name
c0de7a8d
FCE
620 << " entrypc: " << hex << entrypc
621 << " prologue-end: " << line_addr << dec
50e0d793
GH
622 << endl;
623 return true;
624 }
625 else if (line_addr == entrypc)
626 choose_next_line = true;
627 }
628 return false;
bd2b1e68
GH
629 }
630
631
77de5e9e 632 string literal_stmt_for_local(Dwarf_Addr pc,
91eefb1c 633 string const & local,
d9b516ca 634 vector<pair<target_symbol::component_type,
91eefb1c 635 std::string> > const & components)
77de5e9e
GH
636 {
637 assert (cu);
638
639 Dwarf_Die *scopes;
640 Dwarf_Die vardie;
641
7a053d3b 642 int nscopes = dwarf_getscopes (cu, pc, &scopes);
77de5e9e
GH
643 if (nscopes == 0)
644 {
7a053d3b 645 throw semantic_error ("unable to find any scopes containing "
59ff2773 646 + lex_cast_hex<string>(pc)
77de5e9e
GH
647 + " while searching for local '" + local + "'");
648 }
7a053d3b 649
77de5e9e 650 int declaring_scope = dwarf_getscopevar (scopes, nscopes,
7a053d3b
RM
651 local.c_str(),
652 0, NULL, 0, 0,
653 &vardie);
77de5e9e
GH
654 if (declaring_scope < 0)
655 {
656 throw semantic_error ("unable to find local '" + local + "'"
59ff2773 657 + " near pc " + lex_cast_hex<string>(pc));
77de5e9e 658 }
7a053d3b 659
77de5e9e
GH
660 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
661 for (int inner = 0; inner < nscopes; ++inner)
662 {
663 switch (dwarf_tag (&scopes[inner]))
664 {
665 default:
666 continue;
667 case DW_TAG_subprogram:
668 case DW_TAG_entry_point:
669 case DW_TAG_inlined_subroutine: /* XXX */
670 if (inner >= declaring_scope)
671 fb_attr = dwarf_attr_integrate (&scopes[inner],
672 DW_AT_frame_base,
673 &fb_attr_mem);
674 break;
675 }
676 }
677
678 if (sess.verbose)
7a053d3b 679 clog << "finding location for local '" << local
db520b00
FCE
680 << "' near address " << hex << pc
681 << ", module bias " << module_bias << dec
77de5e9e 682 << endl;
7a053d3b
RM
683
684 Dwarf_Attribute attr_mem;
77de5e9e
GH
685 if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
686 throw semantic_error("failed to retrieve location "
687 "attribute for local '" + local + "'");
7a053d3b 688
77de5e9e
GH
689#define obstack_chunk_alloc malloc
690#define obstack_chunk_free free
7a053d3b 691
77de5e9e 692 struct obstack pool;
7a053d3b 693 obstack_init (&pool);
77de5e9e 694 struct location *tail = NULL;
7a053d3b 695 struct location *head = c_translate_location (&pool, 1, module_bias,
77de5e9e
GH
696 &attr_mem, pc,
697 &tail, fb_attr);
698
d9b516ca 699 if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
77de5e9e
GH
700 throw semantic_error("failed to retrieve type "
701 "attribute for local '" + local + "'");
702
d9b516ca
RM
703 Dwarf_Die die_mem, *die = &vardie;
704 unsigned i = 0;
705 while (i < components.size())
706 {
707 die = dwarf_formref_die (&attr_mem, &die_mem);
708 const int typetag = dwarf_tag (die);
709 switch (typetag)
710 {
711 case DW_TAG_typedef:
712 /* Just iterate on the referent type. */
713 break;
91eefb1c 714
d9b516ca
RM
715 case DW_TAG_pointer_type:
716 if (components[i].first == target_symbol::comp_literal_array_index)
717 goto subscript;
91eefb1c 718
d9b516ca
RM
719 c_translate_pointer (&pool, 1, module_bias, die, &tail);
720 break;
91eefb1c 721
d9b516ca
RM
722 case DW_TAG_array_type:
723 if (components[i].first == target_symbol::comp_literal_array_index)
724 {
725 subscript:
726 c_translate_array (&pool, 1, module_bias, die, &tail,
727 NULL, lex_cast<Dwarf_Word>(components[i].second));
728 ++i;
729 }
730 else
731 throw semantic_error("bad field '"
732 + components[i].second
733 + "' for array type");
734 break;
91eefb1c 735
d9b516ca
RM
736 case DW_TAG_structure_type:
737 case DW_TAG_union_type:
738 switch (dwarf_child (die, &die_mem))
739 {
740 case 1: /* No children. */
741 throw semantic_error ("empty struct "
742 + string (dwarf_diename_integrate (die) ?: "<anonymous>"));
743 break;
744 case -1: /* Error. */
745 default: /* Shouldn't happen */
746 throw semantic_error (string (typetag == DW_TAG_union_type ? "union" : "struct")
747 + string (dwarf_diename_integrate (die) ?: "<anonymous>")
748 + string (dwarf_errmsg (-1)));
749 break;
750
751 case 0:
752 break;
753 }
754
755 while (dwarf_tag (die) != DW_TAG_member
756 || ({ const char *member = dwarf_diename_integrate (die);
757 member == NULL || string(member) != components[i].second; }))
758 if (dwarf_siblingof (die, &die_mem) != 0)
759 throw semantic_error ("field name " + components[i].second + " not found");
760
761 if (dwarf_attr_integrate (die, DW_AT_data_member_location,
762 &attr_mem) == NULL)
763 {
764 /* Union members don't usually have a location,
765 but just use the containing union's location. */
766 if (typetag != DW_TAG_union_type)
767 throw semantic_error ("no location for field "
768 + components[i].second
769 + " :" + string(dwarf_errmsg (-1)));
770 }
771 else
772 c_translate_location (&pool, 1, module_bias, &attr_mem, pc,
773 &tail, NULL);
774 ++i;
775 break;
776
777 case DW_TAG_base_type:
778 throw semantic_error ("field "
779 + components[i].second
780 + " vs base type "
781 + string(dwarf_diename_integrate (die) ?: "<anonymous type>"));
782 break;
783 case -1:
784 throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)));
785 break;
786
787 default:
788 throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>")
789 + ": unexpected type tag "
790 + lex_cast<string>(dwarf_tag (die)));
791 break;
792 }
793
794 /* Now iterate on the type in DIE's attribute. */
795 if (dwarf_attr_integrate (die, DW_AT_type, &attr_mem) == NULL)
796 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
797 }
91eefb1c 798
d9b516ca
RM
799 /* Fetch the type DIE corresponding to the final location to be accessed.
800 It must be a base type or a typedef for one. */
801
802 Dwarf_Die typedie_mem;
803 Dwarf_Die *typedie;
804 int typetag;
805 while (1)
806 {
807 typedie = dwarf_formref_die (&attr_mem, &typedie_mem);
808 if (typedie == NULL)
809 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
810 typetag = dwarf_tag (typedie);
811 if (typetag != DW_TAG_typedef)
91eefb1c 812 break;
d9b516ca
RM
813 if (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem) == NULL)
814 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
815 }
91eefb1c 816
d9b516ca
RM
817 if (typetag != DW_TAG_base_type)
818 throw semantic_error ("target location not a base type");
91eefb1c 819
d9b516ca 820 c_translate_fetch (&pool, 1, module_bias, die, typedie, &tail,
77de5e9e 821 "THIS->__retvalue");
7a053d3b 822
77de5e9e
GH
823 size_t bufsz = 1024;
824 char *buf = static_cast<char*>(malloc(bufsz));
825 assert(buf);
7a053d3b 826
77de5e9e
GH
827 FILE *memstream = open_memstream (&buf, &bufsz);
828 assert(memstream);
7a053d3b 829
77de5e9e 830 bool deref = c_emit_location (memstream, head, 1);
a781f401 831 fprintf(memstream, " goto out;\n");
7a053d3b 832
a781f401
FCE
833 // dummy use of deref_fault label, to disable warning if deref() not used
834 fprintf(memstream, "if (0) goto deref_fault;\n");
835
836 // XXX: deref flag not reliable; emit fault label unconditionally
837 if (deref) ;
838 fprintf(memstream,
839 "deref_fault:\n"
840 " c->errorcount++; \n"
841 " goto out;\n");
7a053d3b 842
77de5e9e
GH
843 fclose (memstream);
844 string result(buf);
845 free (buf);
846 return result;
847 }
7a053d3b
RM
848
849
77de5e9e 850
bd2b1e68
GH
851 ~dwflpp()
852 {
853 if (dwfl)
854 dwfl_end(dwfl);
855 }
856};
857
20c6c071 858
7a053d3b 859enum
bd2b1e68 860function_spec_type
7a053d3b 861 {
bd2b1e68
GH
862 function_alone,
863 function_and_file,
7a053d3b 864 function_file_and_line
bd2b1e68
GH
865 };
866
ec4373ff 867
bd2b1e68 868struct dwarf_builder;
77de5e9e
GH
869struct dwarf_query;
870
bd2b1e68 871struct dwarf_derived_probe : public derived_probe
b55bc428 872{
77de5e9e 873 dwarf_derived_probe (dwarf_query & q,
20c6c071 874 Dwarf_Addr addr);
d9b516ca 875
20c6c071 876 string module_name;
a229fcd7
GH
877 string function_name;
878 bool has_statement;
20c6c071 879 Dwarf_Addr addr;
a229fcd7 880 Dwarf_Addr module_bias;
fd6602a0 881 bool has_return;
7a053d3b 882
bd2b1e68 883 // Pattern registration helpers.
7a053d3b 884 static void register_relative_variants(match_node * root,
bd2b1e68 885 dwarf_builder * dw);
7a053d3b 886 static void register_statement_variants(match_node * root,
bd2b1e68 887 dwarf_builder * dw);
fd6602a0
FCE
888 static void register_function_variants(match_node * root,
889 dwarf_builder * dw);
7a053d3b 890 static void register_function_and_statement_variants(match_node * root,
bd2b1e68 891 dwarf_builder * dw);
20c6c071 892 static void register_patterns(match_node * root);
7a053d3b 893
20c6c071
GH
894 virtual void emit_registrations (translator_output * o, unsigned i);
895 virtual void emit_deregistrations (translator_output * o, unsigned i);
896 virtual void emit_probe_entries (translator_output * o, unsigned i);
897 virtual ~dwarf_derived_probe() {}
898};
899
900// Helper struct to thread through the dwfl callbacks.
7a053d3b 901struct
20c6c071
GH
902dwarf_query
903{
5227f1ea
GH
904 dwarf_query(systemtap_session & sess,
905 probe * base_probe,
20c6c071
GH
906 probe_point * base_loc,
907 dwflpp & dw,
908 map<string, literal *> const & params,
909 vector<derived_probe *> & results);
bd2b1e68 910
5227f1ea
GH
911 systemtap_session & sess;
912
bd2b1e68 913 // Parameter extractors.
7a053d3b 914 static bool has_null_param(map<string, literal *> const & params,
bd2b1e68 915 string const & k);
7a053d3b 916 static bool get_string_param(map<string, literal *> const & params,
bd2b1e68 917 string const & k, string & v);
7a053d3b 918 static bool get_number_param(map<string, literal *> const & params,
bd2b1e68 919 string const & k, long & v);
c239d28c
GH
920 static bool get_number_param(map<string, literal *> const & params,
921 string const & k, Dwarf_Addr & v);
b55bc428 922
77de5e9e
GH
923 string pt_regs_member_for_regnum(uint8_t dwarf_regnum);
924
20c6c071 925 vector<derived_probe *> & results;
20c6c071
GH
926
927 bool has_kernel;
928 bool has_process;
929 bool has_module;
7a053d3b
RM
930 string process_val;
931 string module_val;
932 string function_val;
20c6c071
GH
933
934 bool has_function_str;
935 bool has_statement_str;
936 bool has_function_num;
937 bool has_statement_num;
7a053d3b
RM
938 string statement_str_val;
939 string function_str_val;
c239d28c
GH
940 Dwarf_Addr statement_num_val;
941 Dwarf_Addr function_num_val;
20c6c071
GH
942
943 bool has_callees;
7a053d3b 944 long callee_val;
20c6c071
GH
945
946 bool has_return;
947
948 bool has_label;
949 string label_val;
950
951 bool has_relative;
952 long relative_val;
953
954 function_spec_type parse_function_spec(string & spec);
955 function_spec_type spec_type;
956 string function;
957 string file;
958 int line;
959
960 probe * base_probe;
961 probe_point * base_loc;
962 dwflpp & dw;
b55bc428
FCE
963};
964
965struct
7a053d3b 966dwarf_builder
b55bc428
FCE
967 : public derived_probe_builder
968{
bd2b1e68 969 dwarf_builder() {}
5227f1ea 970 virtual void build(systemtap_session & sess,
7a053d3b 971 probe * base,
20c6c071
GH
972 probe_point * location,
973 std::map<std::string, literal *> const & parameters,
974 vector<probe *> & results_to_expand_further,
975 vector<derived_probe *> & finished_results);
b55bc428
FCE
976 virtual ~dwarf_builder() {}
977};
978
7a053d3b
RM
979bool
980dwarf_query::has_null_param(map<string, literal *> const & params,
20c6c071 981 string const & k)
bd2b1e68
GH
982{
983 map<string, literal *>::const_iterator i = params.find(k);
984 if (i != params.end() && i->second == NULL)
985 return true;
986 return false;
987}
988
7a053d3b
RM
989bool
990dwarf_query::get_string_param(map<string, literal *> const & params,
20c6c071 991 string const & k, string & v)
bd2b1e68
GH
992{
993 map<string, literal *>::const_iterator i = params.find(k);
994 if (i == params.end())
995 return false;
996 literal_string * ls = dynamic_cast<literal_string *>(i->second);
997 if (!ls)
998 return false;
999 v = ls->value;
1000 return true;
1001}
1002
7a053d3b
RM
1003bool
1004dwarf_query::get_number_param(map<string, literal *> const & params,
20c6c071 1005 string const & k, long & v)
bd2b1e68
GH
1006{
1007 map<string, literal *>::const_iterator i = params.find(k);
1008 if (i == params.end())
1009 return false;
1010 if (i->second == NULL)
1011 return false;
1012 literal_number * ln = dynamic_cast<literal_number *>(i->second);
1013 if (!ln)
1014 return false;
1015 v = ln->value;
1016 return true;
1017}
1018
c239d28c
GH
1019bool
1020dwarf_query::get_number_param(map<string, literal *> const & params,
1021 string const & k, Dwarf_Addr & v)
1022{
1023 map<string, literal *>::const_iterator i = params.find(k);
1024 if (i == params.end())
1025 return false;
1026 if (i->second == NULL)
1027 return false;
1028 literal_number * ln = dynamic_cast<literal_number *>(i->second);
1029 if (!ln)
1030 return false;
1031 v = static_cast<Dwarf_Addr>(ln->value);
1032 return true;
1033}
1034
77de5e9e 1035
5227f1ea
GH
1036dwarf_query::dwarf_query(systemtap_session & sess,
1037 probe * base_probe,
20c6c071
GH
1038 probe_point * base_loc,
1039 dwflpp & dw,
1040 map<string, literal *> const & params,
1041 vector<derived_probe *> & results)
5227f1ea
GH
1042 : sess(sess),
1043 results(results),
7a053d3b 1044 base_probe(base_probe),
20c6c071
GH
1045 base_loc(base_loc),
1046 dw(dw)
bd2b1e68 1047{
20c6c071 1048
bd2b1e68
GH
1049 // Reduce the query to more reasonable semantic values (booleans,
1050 // extracted strings, numbers, etc).
1051
1052 has_kernel = has_null_param(params, TOK_KERNEL);
1053 has_module = get_string_param(params, TOK_MODULE, module_val);
1054 has_process = get_string_param(params, TOK_PROCESS, process_val);
1055
1056 has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
1057 has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
1058
1059 has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
1060 has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
1061
1062 callee_val = 1;
7a053d3b 1063 has_callees = (has_null_param(params, TOK_CALLEES) ||
bd2b1e68
GH
1064 get_number_param(params, TOK_CALLEES, callee_val));
1065
1066 has_return = has_null_param(params, TOK_RETURN);
1067
1068 has_label = get_string_param(params, TOK_LABEL, label_val);
1069 has_relative = get_number_param(params, TOK_RELATIVE, relative_val);
7a053d3b 1070
bd2b1e68
GH
1071 if (has_function_str)
1072 spec_type = parse_function_spec(function_str_val);
1073 else if (has_statement_str)
1074 spec_type = parse_function_spec(statement_str_val);
7a053d3b 1075}
bd2b1e68
GH
1076
1077
bd2b1e68 1078function_spec_type
20c6c071 1079dwarf_query::parse_function_spec(string & spec)
bd2b1e68
GH
1080{
1081 string::const_iterator i = spec.begin(), e = spec.end();
7a053d3b 1082
bd2b1e68
GH
1083 function.clear();
1084 file.clear();
1085 line = 0;
1086
1087 while (i != e && *i != '@')
1088 {
1089 if (*i == ':')
1090 goto bad;
1091 function += *i++;
1092 }
1093
1094 if (i == e)
1095 {
5227f1ea 1096 if (sess.verbose)
7a053d3b
RM
1097 clog << "parsed '" << spec
1098 << "' -> func '" << function
bd2b1e68
GH
1099 << "'" << endl;
1100 return function_alone;
1101 }
1102
1103 if (i++ == e)
1104 goto bad;
1105
1106 while (i != e && *i != ':')
1107 file += *i++;
7a053d3b 1108
bd2b1e68
GH
1109 if (i == e)
1110 {
5227f1ea 1111 if (sess.verbose)
7a053d3b
RM
1112 clog << "parsed '" << spec
1113 << "' -> func '"<< function
1114 << "', file '" << file
bd2b1e68
GH
1115 << "'" << endl;
1116 return function_and_file;
1117 }
1118
1119 if (i++ == e)
1120 goto bad;
1121
1122 try
1123 {
1124 line = lex_cast<int>(string(i, e));
5227f1ea 1125 if (sess.verbose)
7a053d3b
RM
1126 clog << "parsed '" << spec
1127 << "' -> func '"<< function
1128 << "', file '" << file
bd2b1e68
GH
1129 << "', line " << line << endl;
1130 return function_file_and_line;
1131 }
1132 catch (runtime_error & exn)
1133 {
1134 goto bad;
1135 }
1136
1137 bad:
7a053d3b 1138 throw semantic_error("malformed specification '" + spec + "'",
20c6c071 1139 base_probe->tok);
bd2b1e68
GH
1140}
1141
1142
1143static void
20c6c071 1144query_statement(Dwarf_Addr stmt_addr, dwarf_query * q)
bd2b1e68 1145{
39bcd429
FCE
1146 try
1147 {
1148 // XXX: implement
1149 if (q->has_relative)
1150 throw semantic_error("incomplete: do not know how to interpret .relative",
1151 q->base_probe->tok);
d9b516ca 1152
39bcd429
FCE
1153 q->results.push_back(new dwarf_derived_probe(*q, stmt_addr));
1154 }
1155 catch (const semantic_error& e)
1156 {
1157 q->sess.print_error (e);
1158 }
bd2b1e68
GH
1159}
1160
1161static int
1162query_function(Dwarf_Func * func, void * arg)
1163{
20c6c071 1164 dwarf_query * q = static_cast<dwarf_query *>(arg);
bd2b1e68 1165
39bcd429 1166 try
7a053d3b 1167 {
39bcd429
FCE
1168 // XXX: implement
1169 if (q->has_callees)
1170 throw semantic_error("incomplete: do not know how to interpret .callees",
1171 q->base_probe->tok);
d9b516ca 1172
39bcd429
FCE
1173 if (q->has_label)
1174 throw semantic_error("incomplete: do not know how to interpret .label",
1175 q->base_probe->tok);
d9b516ca 1176
39bcd429 1177 q->dw.focus_on_function(func);
d9b516ca 1178
39bcd429 1179 Dwarf_Addr entry_addr;
d9b516ca 1180
39bcd429 1181 if (q->has_statement_str || q->has_function_str)
d9b516ca 1182 {
39bcd429
FCE
1183 if (q->dw.function_name_matches(q->function))
1184 {
b5d77020
FCE
1185 if (q->sess.verbose)
1186 clog << "focused on function '" << q->dw.function_name
1187 << "', in CU '" << q->dw.cu_name
1188 << "', module '" << q->dw.module_name << "'" << endl;
1189
39bcd429
FCE
1190 // XXX: This code is duplicated below, but it's important
1191 // for performance reasons to test things in this order.
b5d77020 1192
db520b00 1193 if (q->has_statement_str)
39bcd429 1194 {
db520b00
FCE
1195 // XXX: look up address corresponding to statement string,
1196 // which could be any old line within a function definition.
1197 cerr << "WARNING: cannot handle statement "
1198 << q->statement_str_val << " address" << endl;
39bcd429
FCE
1199 return DWARF_CB_OK;
1200 }
db520b00
FCE
1201 if (q->has_return)
1202 {
1203 bool ok = q->dw.function_entrypc (& entry_addr);
1204 if (! ok)
1205 {
1206 if (q->sess.verbose)
1207 cerr << "WARNING: cannot find entry-pc for function "
1208 << q->dw.function_name << endl;
1209 return DWARF_CB_OK;
1210 }
1211 if (q->sess.verbose)
d9b516ca 1212 clog << "function " << q->dw.function_name
db520b00
FCE
1213 << " entrypc: " << hex << entry_addr << dec << endl;
1214 }
1215 else
1216 {
1217 bool ok = q->dw.function_prologue_end(& entry_addr);
1218 if (! ok)
1219 {
1220 // XXX: but this is actually OK for inlined function instances
1221 if (q->sess.verbose)
1222 cerr << "WARNING: cannot find prologue-end PC for function "
1223 << q->dw.function_name << endl;
1224 return DWARF_CB_OK;
1225 }
1226 }
d9b516ca 1227
39bcd429
FCE
1228 // If this function's name matches a function or statement
1229 // pattern, we use its entry pc, but we do not abort iteration
1230 // since there might be other functions matching the pattern.
1231 query_statement(entry_addr, q);
1232 }
1233 }
1234 else
1235 {
1236 if (q->has_function_num || q->has_statement_num)
1237 {
1238 Dwarf_Addr query_addr = (q->has_function_num
1239 ? q->function_num_val
1240 : q->statement_num_val);
d9b516ca 1241
39bcd429 1242 // Adjust module-relative address to global
d9b516ca 1243
39bcd429
FCE
1244 if (q->has_module)
1245 query_addr = q->dw.module_address_to_global(query_addr);
d9b516ca 1246
39bcd429
FCE
1247 if (q->dw.function_includes_global_addr(query_addr))
1248 {
db520b00
FCE
1249 if (q->has_statement_num) // has_statement
1250 entry_addr = 0; // unused, see below
1251 else if (q->has_return) // has_function
39bcd429 1252 {
db520b00
FCE
1253 bool ok = q->dw.function_entrypc (& entry_addr);
1254 if (! ok)
1255 {
1256 if (q->sess.verbose)
1257 cerr << "WARNING: cannot find entry-pc for function "
1258 << q->dw.function_name << endl;
1259 return DWARF_CB_OK;
1260 }
1261 if (q->sess.verbose)
d9b516ca 1262 clog << "function " << q->dw.function_name
db520b00
FCE
1263 << " entrypc: " << hex << entry_addr << dec << endl;
1264 }
1265 else // has_function
1266 {
1267 bool ok = q->dw.function_prologue_end(& entry_addr);
1268 if (! ok)
1269 {
1270 // XXX: but this is actually OK for inlined function instances
1271 if (q->sess.verbose)
1272 cerr << "WARNING: cannot find prologue-end PC for function "
1273 << q->dw.function_name << endl;
1274 return DWARF_CB_OK;
1275 }
39bcd429 1276 }
d9b516ca 1277
39bcd429
FCE
1278 query_statement(q->has_function_num ? entry_addr : query_addr, q);
1279 return DWARF_CB_ABORT;
1280 }
1281 }
1282 }
d9b516ca 1283
39bcd429 1284 return DWARF_CB_OK;
bd2b1e68 1285 }
39bcd429 1286 catch (const semantic_error& e)
bd2b1e68 1287 {
39bcd429
FCE
1288 q->sess.print_error (e);
1289 return DWARF_CB_ABORT;
bd2b1e68 1290 }
bd2b1e68
GH
1291}
1292
1293static int
1294query_cu (Dwarf_Die * cudie, void * arg)
1295{
20c6c071 1296 dwarf_query * q = static_cast<dwarf_query *>(arg);
7a053d3b 1297
39bcd429 1298 try
bd2b1e68 1299 {
39bcd429 1300 q->dw.focus_on_cu(cudie);
d9b516ca 1301
39bcd429
FCE
1302 // If we have enough information in the pattern to skip a CU
1303 // and the CU does not match that information, return early.
1304 if ((q->has_statement_str || q->has_function_str)
1305 && (q->spec_type == function_file_and_line ||
1306 q->spec_type == function_and_file)
1307 && (!q->dw.cu_name_matches(q->file)))
1308 return DWARF_CB_OK;
b5d77020
FCE
1309
1310 if (false && q->sess.verbose)
1311 clog << "focused on CU '" << q->dw.cu_name
1312 << "', in module '" << q->dw.module_name << "'" << endl;
d9b516ca 1313
39bcd429
FCE
1314 if (q->has_statement_str
1315 && (q->spec_type == function_file_and_line)
1316 && q->dw.cu_name_matches(q->file))
1317 {
1318 // If we have a complete file:line statement
1319 // functor (not function functor) landing on
1320 // this CU, we can look up a specific address
1321 // for the statement, and skip scanning
1322 // the remaining functions within the CU.
1323 query_statement(q->dw.global_addr_of_line_in_cu(q->line), q);
1324 }
c239d28c
GH
1325 else if (q->has_function_str
1326 && (q->spec_type == function_file_and_line)
1327 && q->dw.cu_name_matches(q->file))
1328 {
1329 // If we have a complete file:line *function* functor
1330 // landing on this CU, we need to select only the functions
1331 // which land on the line in question. We *could* check each
1332 // function individually but the line->addr lookup is
1333 // expensive, so we do it once here, then temporarily switch
1334 // to a .function(addr) query for the remaining function
1335 // iteration, switching back when we complete.
1336 q->function_num_val = q->dw.global_addr_of_line_in_cu(q->line);
1337 swap(q->has_function_str, q->has_function_num);
1338 q->dw.iterate_over_functions(&query_function, q);
1339 swap(q->has_function_str, q->has_function_num);
1340 }
39bcd429
FCE
1341 else
1342 {
c239d28c
GH
1343 // Otherwise we need to scan all the functions in this CU,
1344 // matching by function name or address, as requested.
39bcd429
FCE
1345 q->dw.iterate_over_functions(&query_function, q);
1346 }
1347 return DWARF_CB_OK;
bd2b1e68 1348 }
39bcd429 1349 catch (const semantic_error& e)
bd2b1e68 1350 {
39bcd429
FCE
1351 q->sess.print_error (e);
1352 return DWARF_CB_ABORT;
bd2b1e68 1353 }
bd2b1e68
GH
1354}
1355
1356static int
1357query_module (Dwfl_Module *mod __attribute__ ((unused)),
1358 void **userdata __attribute__ ((unused)),
1359 const char *name, Dwarf_Addr base,
bd2b1e68
GH
1360 void *arg __attribute__ ((unused)))
1361{
20c6c071 1362 dwarf_query * q = static_cast<dwarf_query *>(arg);
bd2b1e68 1363
39bcd429 1364 try
bd2b1e68 1365 {
39bcd429 1366 q->dw.focus_on_module(mod);
d9b516ca 1367
39bcd429
FCE
1368 // If we have enough information in the pattern to skip a module and
1369 // the module does not match that information, return early.
d9b516ca 1370
39bcd429
FCE
1371 if (q->has_kernel && !q->dw.module_name_matches(TOK_KERNEL))
1372 return DWARF_CB_OK;
d9b516ca 1373
39bcd429
FCE
1374 if (q->has_module && !q->dw.module_name_matches(q->module_val))
1375 return DWARF_CB_OK;
b5d77020
FCE
1376
1377 if (q->sess.verbose)
d9b516ca
RM
1378 clog << "focused on module '" << q->dw.module_name
1379 << "' = [" << hex << q->dw.module_start
1380 << "-" << q->dw.module_end
c0de7a8d 1381 << ", bias " << q->dw.module_bias << "]" << dec << endl;
b5d77020 1382
39bcd429
FCE
1383 if (q->has_function_num || q->has_statement_num)
1384 {
1385 // If we have module("foo").function(0xbeef) or
1386 // module("foo").statement(0xbeef), the address is relative
1387 // to the start of the module, so we seek the function
1388 // number plus the module's bias.
1389 Dwarf_Addr addr;
1390 if (q->has_function_num)
1391 addr = q->function_num_val;
1392 else
1393 addr = q->statement_num_val;
d9b516ca 1394
39bcd429
FCE
1395 if (q->has_kernel)
1396 q->dw.focus_on_cu_containing_global_address(addr);
1397 else
1398 q->dw.focus_on_cu_containing_module_address(addr);
d9b516ca 1399
39bcd429
FCE
1400 q->dw.iterate_over_functions(&query_function, q);
1401 }
50e0d793 1402 else
39bcd429
FCE
1403 {
1404 // Otherwise if we have a function("foo") or statement("foo")
1405 // specifier, we have to scan over all the CUs looking for
1406 // the function in question
1407 assert(q->has_function_str || q->has_statement_str);
1408 q->dw.iterate_over_cus(&query_cu, q);
1409 }
d9b516ca 1410
39bcd429
FCE
1411 // If we just processed the module "kernel", and the user asked for
1412 // the kernel pattern, there's no need to iterate over any further
1413 // modules
d9b516ca 1414
39bcd429
FCE
1415 if (q->has_kernel && q->dw.module_name_matches(TOK_KERNEL))
1416 return DWARF_CB_ABORT;
d9b516ca 1417
39bcd429 1418 return DWARF_CB_OK;
7a053d3b 1419 }
39bcd429 1420 catch (const semantic_error& e)
bd2b1e68 1421 {
39bcd429
FCE
1422 q->sess.print_error (e);
1423 return DWARF_CB_ABORT;
bd2b1e68 1424 }
bd2b1e68
GH
1425}
1426
77de5e9e
GH
1427struct
1428var_expanding_copy_visitor
1429 : public deep_copy_visitor
1430{
77de5e9e
GH
1431 static unsigned tick;
1432
1433 dwarf_query & q;
77de5e9e
GH
1434 Dwarf_Addr addr;
1435
7a053d3b 1436 var_expanding_copy_visitor(dwarf_query & q, Dwarf_Addr a)
d7f3e0c5 1437 : q(q), addr(a)
77de5e9e 1438 {}
d7f3e0c5 1439 void visit_target_symbol (target_symbol* e);
77de5e9e
GH
1440};
1441
1442
1443unsigned var_expanding_copy_visitor::tick = 0;
1444
1445
1446void
d7f3e0c5 1447var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
77de5e9e 1448{
d7f3e0c5 1449 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
d9b516ca 1450
d7f3e0c5 1451 if (is_active_lvalue(e))
77de5e9e 1452 {
d7f3e0c5
GH
1453 throw semantic_error("read-only special variable "
1454 + e->base_name + " used as lvalue", e->tok);
77de5e9e 1455 }
d9b516ca 1456
d7f3e0c5
GH
1457 string fname = "get_" + e->base_name.substr(1) + "_" + lex_cast<string>(tick++);
1458
1459 // synthesize a function
1460 functiondecl *fdecl = new functiondecl;
1461 embeddedcode *ec = new embeddedcode;
d9b516ca 1462 ec->code = q.dw.literal_stmt_for_local(addr,
91eefb1c
GH
1463 e->base_name.substr(1),
1464 e->components);
d7f3e0c5
GH
1465 fdecl->name = fname;
1466 fdecl->body = ec;
1467 fdecl->type = pe_long;
1468 q.sess.functions.push_back(fdecl);
d9b516ca 1469
d7f3e0c5
GH
1470 // synthesize a call
1471 functioncall* n = new functioncall;
1472 n->tok = e->tok;
1473 n->function = fname;
1474 n->referent = NULL;
d9b516ca 1475 provide <functioncall*> (this, n);
77de5e9e
GH
1476}
1477
1478
7a053d3b 1479dwarf_derived_probe::dwarf_derived_probe (dwarf_query & q,
20c6c071 1480 Dwarf_Addr addr)
a229fcd7
GH
1481 : derived_probe (NULL),
1482 module_name(q.dw.module_name),
1483 function_name(q.dw.function_name),
1484 has_statement(q.has_statement_str || q.has_statement_num),
fd6602a0 1485 addr(addr),
a229fcd7 1486 module_bias(q.dw.module_bias),
fd6602a0 1487 has_return (q.has_return)
bd2b1e68 1488{
a229fcd7
GH
1489 // first synthesize an "expanded" location
1490 vector<probe_point::component*> comps;
1491 comps.push_back
1492 (module_name == TOK_KERNEL
1493 ? new probe_point::component(TOK_KERNEL)
db520b00 1494 : new probe_point::component(TOK_MODULE, new literal_string(module_name)));
b5d77020 1495
db520b00
FCE
1496 string fn_or_stmt;
1497 if (q.has_function_str || q.has_function_num)
1498 fn_or_stmt = "function";
1499 else
1500 fn_or_stmt = "statement";
a229fcd7 1501
db520b00
FCE
1502 if (q.has_function_str || q.has_statement_str)
1503 {
1504 string retro_name;;
1505 if (! function_name.empty())
1506 retro_name = function_name + "@" + q.dw.cu_name; // XXX: add line number
1507 else if (q.has_function_str)
1508 retro_name = q.function_str_val;
1509 else // has_statement_str
1510 retro_name = q.statement_str_val;
1511 // XXX: actually the statement_str case is not yet adequately
1512 // handled in the search code
1513
1514 comps.push_back
1515 (new probe_point::component
1516 (fn_or_stmt, new literal_string (retro_name)));
1517 }
1518 else if (q.has_function_num || q.has_statement_num)
1519 {
1520 Dwarf_Addr retro_addr;
1521 if (q.has_function_num)
1522 retro_addr = q.function_num_val;
1523 else
1524 retro_addr = q.statement_num_val;
1525
1526 comps.push_back (new probe_point::component
1527 (fn_or_stmt,
1528 new literal_number(retro_addr))); // XXX: should be hex if possible
a229fcd7
GH
1529 }
1530
db520b00 1531 if (has_return)
a229fcd7 1532 comps.push_back
db520b00 1533 (new probe_point::component(TOK_RETURN));
d9b516ca 1534
a229fcd7
GH
1535 assert(q.base_probe->locations.size() > 0);
1536 locations.push_back(new probe_point(comps, q.base_probe->locations[0]->tok));
1537
1538 // Now make a local-variable-expanded copy of the probe body
77de5e9e
GH
1539 var_expanding_copy_visitor v (q, addr);
1540 require <block*> (&v, &(this->body), q.base_probe->body);
1541 this->tok = q.base_probe->tok;
bd2b1e68
GH
1542}
1543
7a053d3b 1544void
20c6c071 1545dwarf_derived_probe::register_relative_variants(match_node * root,
bd2b1e68
GH
1546 dwarf_builder * dw)
1547{
1548 // Here we match 2 forms:
1549 //
1550 // .
1551 // .relative(NN)
1552
20c6c071
GH
1553 root->bind(dw);
1554 root->bind_num(TOK_RELATIVE)->bind(dw);
bd2b1e68
GH
1555}
1556
7a053d3b 1557void
20c6c071 1558dwarf_derived_probe::register_statement_variants(match_node * root,
bd2b1e68
GH
1559 dwarf_builder * dw)
1560{
1561 // Here we match 3 forms:
1562 //
1563 // .
1564 // .return
1565 // .label("foo")
7a053d3b 1566
bd2b1e68 1567 register_relative_variants(root, dw);
20c6c071 1568 register_relative_variants(root->bind_str(TOK_LABEL), dw);
bd2b1e68
GH
1569}
1570
7a053d3b 1571void
fd6602a0 1572dwarf_derived_probe::register_function_variants(match_node * root,
bd2b1e68
GH
1573 dwarf_builder * dw)
1574{
a229fcd7 1575 // Here we match 4 forms:
bd2b1e68
GH
1576 //
1577 // .
fd6602a0 1578 // .return
bd2b1e68
GH
1579 // .callees
1580 // .callees(N)
1581 //
1582 // The last form permits N-level callee resolving without any
1583 // recursive .callees.callees.callees... pattern-matching on our part.
1584
fd6602a0
FCE
1585 root->bind(dw);
1586 root->bind(TOK_RETURN)->bind(dw);
1587 root->bind(TOK_CALLEES)->bind(dw);
1588 root->bind_num(TOK_CALLEES)->bind(dw);
bd2b1e68
GH
1589}
1590
7a053d3b 1591void
20c6c071 1592dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
bd2b1e68
GH
1593 dwarf_builder * dw)
1594{
1595 // Here we match 4 forms:
1596 //
1597 // .function("foo")
1598 // .function(0xdeadbeef)
1599 // .statement("foo")
1600 // .statement(0xdeadbeef)
1601
fd6602a0
FCE
1602 register_function_variants(root->bind_str(TOK_FUNCTION), dw);
1603 register_function_variants(root->bind_num(TOK_FUNCTION), dw);
20c6c071
GH
1604 register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
1605 register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
bd2b1e68
GH
1606}
1607
1608void
20c6c071 1609dwarf_derived_probe::register_patterns(match_node * root)
bd2b1e68
GH
1610{
1611 dwarf_builder *dw = new dwarf_builder();
1612
1613 // Here we match 3 forms:
1614 //
1615 // .kernel
1616 // .module("foo")
1617 // .process("foo")
1618
20c6c071 1619 register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
fe3d01fa 1620 // XXX: may need to disable these for 2005-08 release
20c6c071
GH
1621 register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
1622 register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
bd2b1e68
GH
1623}
1624
7a053d3b 1625static string
ec4373ff 1626probe_entry_function_name(unsigned probenum)
b55bc428 1627{
ec4373ff
GH
1628 return "dwarf_kprobe_" + lex_cast<string>(probenum) + "_enter";
1629}
1630
7a053d3b 1631static string
20c6c071 1632probe_entry_struct_kprobe_name(unsigned probenum)
ec4373ff 1633{
20c6c071 1634 return "dwarf_kprobe_" + lex_cast<string>(probenum);
ec4373ff
GH
1635}
1636
7a053d3b 1637void
20c6c071 1638dwarf_derived_probe::emit_registrations (translator_output* o, unsigned probenum)
ec4373ff 1639{
59ff2773 1640 if (! (module_name.empty() || module_name == "kernel"))
ec4373ff 1641 {
59ff2773
FCE
1642 // XXX: lock module_name in memory
1643 }
1644
1645 if (has_return)
1646 {
1647 o->newline() << probe_entry_struct_kprobe_name(probenum)
db520b00 1648 << ".kp.addr = (void *) 0x" << hex << addr << ";" << dec;
59ff2773
FCE
1649 o->newline() << "rc = register_kretprobe (&"
1650 << probe_entry_struct_kprobe_name(probenum)
1651 << ");";
ec4373ff 1652 }
20c6c071 1653 else
bd2b1e68 1654 {
59ff2773 1655 o->newline() << probe_entry_struct_kprobe_name(probenum)
db520b00 1656 << ".addr = (void *) 0x" << hex << addr << ";" << dec;
7a053d3b 1657 o->newline() << "rc = register_kprobe (&"
59ff2773
FCE
1658 << probe_entry_struct_kprobe_name(probenum)
1659 << ");";
bd2b1e68 1660 }
b55bc428
FCE
1661}
1662
7a053d3b 1663void
ec4373ff 1664dwarf_derived_probe::emit_deregistrations (translator_output* o, unsigned probenum)
b55bc428 1665{
fd6602a0
FCE
1666 if (has_return)
1667 o->newline() << "unregister_kretprobe (& "
1668 << probe_entry_struct_kprobe_name(probenum)
1669 << ");";
1670 else
1671 o->newline() << "unregister_kprobe (& "
1672 << probe_entry_struct_kprobe_name(probenum)
1673 << ");";
59ff2773
FCE
1674
1675 if (! (module_name.empty() || module_name == "kernel"))
1676 {
1677 // XXX: unlock module_name
1678 }
ec4373ff
GH
1679}
1680
7a053d3b 1681void
ec4373ff
GH
1682dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum)
1683{
ec4373ff 1684
7a053d3b 1685 // Construct a single entry function, and a struct kprobe pointing into
20c6c071 1686 // the entry function. The entry function will call the probe function.
20c6c071 1687 o->newline();
3d49c615 1688 o->newline() << "static int ";
9e6edd10
FCE
1689 o->newline() << probe_entry_function_name(probenum) << " (";
1690 if (has_return)
1691 o->line() << "struct kretprobe_instance *_ignored";
1692 else
1693 o->line() << "struct kprobe *_ignored";
1694 o->line() << ", struct pt_regs *regs) {";
3d49c615 1695 o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
bfb3d2d2
FCE
1696 o->newline();
1697
1698 // A precondition for running a probe handler is that we're in RUNNING
1699 // state (not ERROR), and that no one else is already using this context.
1700 o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
3d49c615 1701 o->newline(1) << "return 0;";
bfb3d2d2
FCE
1702 o->newline(-1) << "if (c->busy) {";
1703 o->newline(1) << "printk (KERN_ERR \"probe reentrancy\");";
1704 o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
3d49c615 1705 o->newline() << "return 0;";
bfb3d2d2
FCE
1706 o->newline(-1) << "}";
1707 o->newline();
1708
ec4373ff 1709 o->newline() << "c->busy ++;";
bfb3d2d2
FCE
1710 o->newline() << "mb ();"; // for smp
1711 o->newline() << "c->errorcount = 0;";
ec4373ff
GH
1712 o->newline() << "c->actioncount = 0;";
1713 o->newline() << "c->nesting = 0;";
3d49c615 1714 o->newline() << "c->regs = regs;";
ec4373ff
GH
1715 // NB: locals are initialized by probe function itself
1716 o->newline() << "probe_" << probenum << " (c);";
bfb3d2d2
FCE
1717
1718 // see translate.cxx: visit_functioncall and elsewhere to see all the
1719 // possible context indications that a probe exited prematurely
3d49c615
FCE
1720 o->newline() << "if (c->errorcount || c->actioncount > MAXACTION"
1721 << " || c->nesting+2 >= MAXNESTING) {";
1722 o->newline(1) << "printk (KERN_ERR \"probe execution failure (e%d,n%d,a%d)\",";
bfb3d2d2
FCE
1723 o->newline(1) << "c->errorcount, c->nesting, c->actioncount);";
1724 o->newline(-1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
1725 o->newline(-1) << "}";
1726
ec4373ff 1727 o->newline() << "c->busy --;";
bfb3d2d2
FCE
1728 o->newline() << "mb ();";
1729
3d49c615 1730 o->newline() << "return 0;";
ec4373ff
GH
1731 o->newline(-1) << "}" << endl;
1732
20c6c071 1733 o->newline();
fd6602a0
FCE
1734 if (has_return)
1735 {
1736 o->newline() << "static struct kretprobe "
1737 << probe_entry_struct_kprobe_name(probenum)
1738 << "= {";
db520b00 1739 o->newline(1) << ".kp.addr = 0," ;
fd6602a0
FCE
1740 o->newline() << ".handler = &" << probe_entry_function_name(probenum);
1741 o->newline(-1) << "};";
1742 }
1743 else
1744 {
1745 o->newline() << "static struct kprobe "
1746 << probe_entry_struct_kprobe_name(probenum)
1747 << "= {";
db520b00 1748 o->newline(1) << ".addr = 0," ;
fd6602a0
FCE
1749 o->newline() << ".pre_handler = &" << probe_entry_function_name(probenum);
1750 o->newline(-1) << "};";
1751 }
20c6c071
GH
1752 o->newline();
1753}
ec4373ff 1754
20c6c071
GH
1755
1756void
5227f1ea 1757dwarf_builder::build(systemtap_session & sess,
7a053d3b 1758 probe * base,
20c6c071
GH
1759 probe_point * location,
1760 std::map<std::string, literal *> const & parameters,
1761 vector<probe *> & results_to_expand_further,
1762 vector<derived_probe *> & finished_results)
1763{
1764
5227f1ea
GH
1765 dwflpp dw(sess);
1766 dwarf_query q(sess, base, location, dw, parameters, finished_results);
20c6c071
GH
1767
1768 dw.setup(q.has_kernel || q.has_module);
1769
d9b516ca 1770 if (q.has_kernel
50e0d793 1771 && (q.has_function_num || q.has_statement_num))
20c6c071 1772 {
50e0d793
GH
1773 // If we have kernel.function(0xbeef), or
1774 // kernel.statement(0xbeef) the address is global (relative to
1775 // the kernel) and we can seek directly to the module and cudie
1776 // in question.
d9b516ca
RM
1777 Dwarf_Addr a = (q.has_function_num
1778 ? q.function_num_val
50e0d793
GH
1779 : q.statement_num_val);
1780 dw.focus_on_module_containing_global_address(a);
1781 dw.focus_on_cu_containing_global_address(a);
20c6c071
GH
1782 dw.iterate_over_functions(&query_function, &q);
1783 }
7a053d3b 1784 else
20c6c071
GH
1785 {
1786 // Otherwise we have module("foo"), kernel.statement("foo"), or
1787 // kernel.function("foo"); in these cases we need to scan all
1788 // the modules.
7a053d3b 1789 assert((q.has_kernel && q.has_function_str) ||
20c6c071
GH
1790 (q.has_kernel && q.has_statement_str) ||
1791 (q.has_module));
1792 dw.iterate_over_modules(&query_module, &q);
1793 }
b55bc428
FCE
1794}
1795
1796
b55bc428 1797// ------------------------------------------------------------------------
bd2b1e68 1798// Standard tapset registry.
b55bc428
FCE
1799// ------------------------------------------------------------------------
1800
7a053d3b 1801void
f8220a7b 1802register_standard_tapsets(systemtap_session & s)
b55bc428 1803{
bd2b1e68 1804 // Rudimentary binders for begin and end targets
f8220a7b
GH
1805 s.pattern_root->bind("begin")->bind(new be_builder(true));
1806 s.pattern_root->bind("end")->bind(new be_builder(false));
b98a8d73 1807
14d0763f 1808 // kernel/module parts
f8220a7b 1809 dwarf_derived_probe::register_patterns(s.pattern_root);
b55bc428 1810}
This page took 0.231347 seconds and 5 git commands to generate.