]> sourceware.org Git - systemtap.git/blame - tapsets.cxx
Make a real type for target_symbol->components
[systemtap.git] / tapsets.cxx
CommitLineData
56e12059 1// tapset resolution
12b44fb3 2// Copyright (C) 2005-2009 Red Hat Inc.
aa30ccd3 3// Copyright (C) 2005-2007 Intel Corporation.
0b8f6579 4// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
56e12059
FCE
5//
6// This file is part of systemtap, and is free software. You can
7// redistribute it and/or modify it under the terms of the GNU General
8// Public License (GPL); either version 2, or (at your option) any
9// later version.
10
11#include "config.h"
12#include "staptree.h"
13#include "elaborate.h"
b55bc428 14#include "tapsets.h"
93646f4d 15#include "task_finder.h"
56e12059 16#include "translate.h"
dc38c0ae 17#include "session.h"
72dbc915 18#include "util.h"
0a6f5a3f 19#include "buildrun.h"
86bf665e 20#include "dwarf_wrappers.h"
2e67a43b 21#include "auto_free.h"
b278033a 22#include "hash.h"
440f755a 23#include "dwflpp.h"
bd2b1e68 24
3b579393
FCE
25#include <cstdlib>
26#include <algorithm>
bd2b1e68 27#include <deque>
56e12059 28#include <iostream>
bd2b1e68 29#include <map>
ec4373ff 30#include <set>
56e12059 31#include <sstream>
bd2b1e68 32#include <stdexcept>
b55bc428 33#include <vector>
e36387d7 34#include <cstdarg>
29e64872 35#include <cassert>
1969b5bc 36#include <iomanip>
f781f849 37#include <cerrno>
bd2b1e68
GH
38
39extern "C" {
df8fadee 40#include <fcntl.h>
bd2b1e68 41#include <elfutils/libdwfl.h>
7a053d3b 42#include <elfutils/libdw.h>
77de5e9e
GH
43#include <dwarf.h>
44#include <elf.h>
45#include <obstack.h>
b20febf3 46#include <glob.h>
30a279be 47#include <fnmatch.h>
5f0a03a6 48#include <stdio.h>
349dc70e 49#include <sys/types.h>
4b1ad75e
RM
50
51#define __STDC_FORMAT_MACROS
52#include <inttypes.h>
bd2b1e68 53}
77de5e9e 54
56e12059
FCE
55
56using namespace std;
2171f774 57using namespace __gnu_cxx;
56e12059 58
46b84a80 59
b20febf3 60
b20febf3
FCE
61// ------------------------------------------------------------------------
62void
a58d79d0 63common_probe_entryfn_prologue (translator_output* o, string statestr,
c12d974f 64 string new_pp,
912e8c59 65 bool overload_processing)
b20febf3 66{
72d18b98 67 o->newline() << "struct context* __restrict__ c;";
e0a17418
JS
68 o->newline() << "#if !INTERRUPTIBLE";
69 o->newline() << "unsigned long flags;";
70 o->newline() << "#endif";
b20febf3 71
a58d79d0
DS
72 if (overload_processing)
73 o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
74 else
75 o->newline() << "#ifdef STP_TIMING";
76 o->newline() << "cycles_t cycles_atstart = get_cycles ();";
b20febf3 77 o->newline() << "#endif";
b20febf3 78
e0a17418
JS
79 o->newline() << "#if INTERRUPTIBLE";
80 o->newline() << "preempt_disable ();";
81 o->newline() << "#else";
82 o->newline() << "local_irq_save (flags);";
83 o->newline() << "#endif";
b20febf3 84
c931ec8a 85 // Check for enough free enough stack space
d05a1d00 86 o->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space
a63401b1 87 o->newline(1) << "< (MINSTACKSPACE + sizeof (struct thread_info)))) {"; // needed space
d05a1d00
FCE
88 // XXX: may need porting to platforms where task_struct is not at bottom of kernel stack
89 // NB: see also CONFIG_DEBUG_STACKOVERFLOW
b3c3ca7c
FCE
90 o->newline() << "atomic_inc (& skipped_count);";
91 o->newline() << "#ifdef STP_TIMING";
92 o->newline() << "atomic_inc (& skipped_count_lowstack);";
93 o->newline() << "#endif";
c931ec8a
FCE
94 o->newline() << "goto probe_epilogue;";
95 o->newline(-1) << "}";
96
b20febf3
FCE
97 o->newline() << "if (atomic_read (&session_state) != " << statestr << ")";
98 o->newline(1) << "goto probe_epilogue;";
99 o->indent(-1);
9a604fac 100
a44a0785 101 o->newline() << "c = per_cpu_ptr (contexts, smp_processor_id());";
b3c3ca7c 102 o->newline() << "if (atomic_inc_return (& c->busy) != 1) {";
9c736061
FCE
103 o->newline(1) << "#if !INTERRUPTIBLE";
104 o->newline() << "atomic_inc (& skipped_count);";
105 o->newline() << "#endif";
b3c3ca7c
FCE
106 o->newline() << "#ifdef STP_TIMING";
107 o->newline() << "atomic_inc (& skipped_count_reentrant);";
c12d974f
FCE
108 o->newline() << "#ifdef DEBUG_REENTRANCY";
109 o->newline() << "_stp_warn (\"Skipped %s due to %s residency on cpu %u\\n\", "
110 << new_pp << ", c->probe_point ?: \"?\", smp_processor_id());";
111 // NB: There is a conceivable race condition here with reading
112 // c->probe_point, knowing that this other probe is sort of running.
113 // However, in reality, it's interrupted. Plus even if it were able
114 // to somehow start again, and stop before we read c->probe_point,
115 // at least we have that ?: "?" bit in there to avoid a NULL deref.
116 o->newline() << "#endif";
b3c3ca7c 117 o->newline() << "#endif";
9a604fac 118 o->newline() << "atomic_dec (& c->busy);";
b20febf3 119 o->newline() << "goto probe_epilogue;";
9a604fac
FCE
120 o->newline(-1) << "}";
121 o->newline();
1e00cfb1 122 o->newline() << "c->last_stmt = 0;";
9a604fac 123 o->newline() << "c->last_error = 0;";
9a604fac 124 o->newline() << "c->nesting = 0;";
22f8b401 125 o->newline() << "c->regs = 0;";
b916df9c 126 o->newline() << "c->unwaddr = 0;";
c12d974f 127 o->newline() << "c->probe_point = " << new_pp << ";";
b916df9c 128 // reset unwound address cache
fcff848e 129 o->newline() << "c->pi = 0;";
9addf322 130 o->newline() << "c->regparm = 0;";
bc54e71c
MH
131 o->newline() << "c->marker_name = NULL;";
132 o->newline() << "c->marker_format = NULL;";
e0a17418
JS
133
134 o->newline() << "#if INTERRUPTIBLE";
135 o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;";
136 o->newline() << "#else";
137 o->newline() << "c->actionremaining = MAXACTION;";
138 o->newline() << "#endif";
dbb68664
FCE
139 o->newline() << "#ifdef STP_TIMING";
140 o->newline() << "c->statp = 0;";
141 o->newline() << "#endif";
9915575b
FCE
142 // NB: The following would actually be incorrect.
143 // That's because cycles_sum/cycles_base values are supposed to survive
144 // between consecutive probes. Periodically (STP_OVERLOAD_INTERVAL
145 // cycles), the values will be reset.
146 /*
f0e6dc63
FCE
147 o->newline() << "#ifdef STP_OVERLOAD";
148 o->newline() << "c->cycles_sum = 0;";
149 o->newline() << "c->cycles_base = 0;";
41c262f3 150 o->newline() << "#endif";
9915575b 151 */
b20febf3 152}
9a604fac 153
a44a0785 154
b20febf3 155void
a58d79d0 156common_probe_entryfn_epilogue (translator_output* o,
912e8c59 157 bool overload_processing)
b20febf3 158{
a58d79d0
DS
159 if (overload_processing)
160 o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
161 else
162 o->newline() << "#ifdef STP_TIMING";
dbb68664 163 o->newline() << "{";
a58d79d0
DS
164 o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
165 // NB: we truncate cycles counts to 32 bits. Perhaps it should be
166 // fewer, if the hardware counter rolls over really quickly. We
167 // handle 32-bit wraparound here.
168 o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
169 o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
170 o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
171 o->indent(-1);
dbb68664 172
a58d79d0 173 o->newline() << "#ifdef STP_TIMING";
dbb68664 174 o->newline() << "if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);";
a58d79d0
DS
175 o->newline() << "#endif";
176
177 if (overload_processing)
178 {
179 o->newline() << "#ifdef STP_OVERLOAD";
180 o->newline() << "{";
181 // If the cycle count has wrapped (cycles_atend > cycles_base),
182 // let's go ahead and pretend the interval has been reached.
183 // This should reset cycles_base and cycles_sum.
184 o->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)";
185 o->newline(1) << "? (cycles_atend - c->cycles_base)";
186 o->newline() << ": (STP_OVERLOAD_INTERVAL + 1);";
187 o->newline(-1) << "c->cycles_sum += cycles_elapsed;";
188
189 // If we've spent more than STP_OVERLOAD_THRESHOLD cycles in a
190 // probe during the last STP_OVERLOAD_INTERVAL cycles, the probe
191 // has overloaded the system and we need to quit.
192 o->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {";
193 o->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {";
194 o->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");";
195 o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
551e9f14 196 o->newline() << "atomic_inc (&error_count);";
a58d79d0
DS
197 o->newline(-1) << "}";
198
199 o->newline() << "c->cycles_base = cycles_atend;";
200 o->newline() << "c->cycles_sum = 0;";
201 o->newline(-1) << "}";
202 o->newline(-1) << "}";
203 o->newline() << "#endif";
204 }
205
440f755a
JS
206 o->newline(-1) << "}";
207 o->newline() << "#endif";
e57b735a 208
440f755a
JS
209 o->newline() << "c->probe_point = 0;"; // vacated
210 o->newline() << "if (unlikely (c->last_error && c->last_error[0])) {";
211 o->newline(1) << "if (c->last_stmt != NULL)";
212 o->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);";
213 o->newline(-1) << "else";
214 o->newline(1) << "_stp_softerror (\"%s\", c->last_error);";
215 o->indent(-1);
216 o->newline() << "atomic_inc (& error_count);";
217 o->newline() << "if (atomic_read (& error_count) > MAXERRORS) {";
218 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
219 o->newline() << "_stp_exit ();";
220 o->newline(-1) << "}";
221 o->newline(-1) << "}";
222 o->newline() << "atomic_dec (&c->busy);";
e57b735a 223
440f755a
JS
224 o->newline(-1) << "probe_epilogue:"; // context is free
225 o->indent(1);
e57b735a 226
440f755a
JS
227 // Check for excessive skip counts.
228 o->newline() << "if (unlikely (atomic_read (& skipped_count) > MAXSKIPPED)) {";
229 o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
230 o->newline() << "_stp_exit ();";
231 o->newline(-1) << "}";
e57b735a 232
440f755a
JS
233 o->newline() << "#if INTERRUPTIBLE";
234 o->newline() << "preempt_enable_no_resched ();";
235 o->newline() << "#else";
236 o->newline() << "local_irq_restore (flags);";
237 o->newline() << "#endif";
238}
e57b735a 239
e57b735a 240
440f755a 241// ------------------------------------------------------------------------
e57b735a 242
440f755a
JS
243// ------------------------------------------------------------------------
244// Dwarf derived probes. "We apologize for the inconvience."
245// ------------------------------------------------------------------------
e57b735a 246
4627ed58
JS
247static const string TOK_KERNEL("kernel");
248static const string TOK_MODULE("module");
249static const string TOK_FUNCTION("function");
250static const string TOK_INLINE("inline");
251static const string TOK_CALL("call");
252static const string TOK_RETURN("return");
253static const string TOK_MAXACTIVE("maxactive");
254static const string TOK_STATEMENT("statement");
255static const string TOK_ABSOLUTE("absolute");
256static const string TOK_PROCESS("process");
257static const string TOK_MARK("mark");
258static const string TOK_TRACE("trace");
259static const string TOK_LABEL("label");
e57b735a 260
1adf8ef1 261static int query_cu (Dwarf_Die * cudie, void * arg);
e57b735a 262
440f755a
JS
263// Can we handle this query with just symbol-table info?
264enum dbinfo_reqt
265{
266 dbr_unknown,
267 dbr_none, // kernel.statement(NUM).absolute
268 dbr_need_symtab, // can get by with symbol table if there's no dwarf
269 dbr_need_dwarf
270};
e57b735a 271
20e4a32c 272
440f755a
JS
273struct base_query; // forward decls
274struct dwarf_query;
275struct dwflpp;
276struct symbol_table;
20e4a32c 277
a781f401 278
440f755a
JS
279struct
280symbol_table
281{
282 module_info *mod_info; // associated module
283 map<string, func_info*> map_by_name;
1c6b77e5
JS
284 multimap<Dwarf_Addr, func_info*> map_by_addr;
285 typedef multimap<Dwarf_Addr, func_info*>::iterator iterator_t;
440f755a
JS
286 typedef pair<iterator_t, iterator_t> range_t;
287#ifdef __powerpc__
288 GElf_Word opd_section;
289#endif
440f755a
JS
290 void add_symbol(const char *name, bool weak, Dwarf_Addr addr,
291 Dwarf_Addr *high_addr);
440f755a 292 enum info_status read_symbols(FILE *f, const string& path);
83ca3872
MW
293 enum info_status read_from_elf_file(const string& path,
294 const systemtap_session &sess);
295 enum info_status read_from_text_file(const string& path,
296 const systemtap_session &sess);
440f755a
JS
297 enum info_status get_from_elf();
298 void prepare_section_rejection(Dwfl_Module *mod);
299 bool reject_section(GElf_Word section);
440f755a
JS
300 void purge_syscall_stubs();
301 func_info *lookup_symbol(const string& name);
302 Dwarf_Addr lookup_symbol_address(const string& name);
303 func_info *get_func_containing_address(Dwarf_Addr addr);
7a053d3b 304
440f755a
JS
305 symbol_table(module_info *mi) : mod_info(mi) {}
306 ~symbol_table();
307};
77de5e9e 308
440f755a
JS
309static bool null_die(Dwarf_Die *die)
310{
311 static Dwarf_Die null = { 0 };
312 return (!die || !memcmp(die, &null, sizeof(null)));
313}
c4ce66a1
JS
314
315
7a053d3b 316enum
bd2b1e68 317function_spec_type
7a053d3b 318 {
bd2b1e68
GH
319 function_alone,
320 function_and_file,
7a053d3b 321 function_file_and_line
bd2b1e68
GH
322 };
323
ec4373ff 324
bd2b1e68 325struct dwarf_builder;
77de5e9e 326
2930abc7 327
b20febf3
FCE
328// XXX: This class is a candidate for subclassing to separate
329// the relocation vs non-relocation variants. Likewise for
330// kprobe vs kretprobe variants.
331
332struct dwarf_derived_probe: public derived_probe
b55bc428 333{
b20febf3
FCE
334 dwarf_derived_probe (const string& function,
335 const string& filename,
336 int line,
337 const string& module,
338 const string& section,
339 Dwarf_Addr dwfl_addr,
2930abc7 340 Dwarf_Addr addr,
b20febf3
FCE
341 dwarf_query & q,
342 Dwarf_Die* scope_die);
20e4a32c 343
b20febf3
FCE
344 string module;
345 string section;
346 Dwarf_Addr addr;
2930abc7 347 bool has_return;
c9bad430
DS
348 bool has_maxactive;
349 long maxactive_val;
b95e2b79 350 bool access_vars;
2930abc7 351
b8da0ad1 352 void printsig (std::ostream &o) const;
b20febf3 353 void join_group (systemtap_session& s);
9020300d
FCE
354 void emit_probe_local_init(translator_output * o);
355
0a98fd42
JS
356 string args;
357 void saveargs(Dwarf_Die* scope_die);
358 void printargs(std::ostream &o) const;
359
bd2b1e68 360 // Pattern registration helpers.
7a053d3b 361 static void register_statement_variants(match_node * root,
bd2b1e68 362 dwarf_builder * dw);
fd6602a0
FCE
363 static void register_function_variants(match_node * root,
364 dwarf_builder * dw);
7a053d3b 365 static void register_function_and_statement_variants(match_node * root,
bd2b1e68 366 dwarf_builder * dw);
c4ce66a1 367 static void register_patterns(systemtap_session& s);
20c6c071
GH
368};
369
dc38c0ae 370
6d0f3f0c
FCE
371struct uprobe_derived_probe: public derived_probe
372{
373 bool return_p;
374 string module; // * => unrestricted
375 int pid; // 0 => unrestricted
376 string section; // empty => absolute address
377 Dwarf_Addr address;
378 // bool has_maxactive;
379 // long maxactive_val;
0973d815 380
6d0f3f0c
FCE
381 uprobe_derived_probe (const string& function,
382 const string& filename,
383 int line,
384 const string& module,
385 int pid,
386 const string& section,
387 Dwarf_Addr dwfl_addr,
388 Dwarf_Addr addr,
389 dwarf_query & q,
390 Dwarf_Die* scope_die);
391
0973d815
FCE
392 // alternate constructor for process(PID).statement(ADDR).absolute
393 uprobe_derived_probe (probe *base,
394 probe_point *location,
395 int pid,
396 Dwarf_Addr addr,
397 bool return_p);
398
9ace370f
JS
399 string args;
400 void saveargs(Dwarf_Die* scope_die);
401 void printargs(std::ostream &o) const;
402
6d0f3f0c
FCE
403 void printsig (std::ostream &o) const;
404 void join_group (systemtap_session& s);
405};
406
dc38c0ae
DS
407struct dwarf_derived_probe_group: public derived_probe_group
408{
409private:
b20febf3
FCE
410 multimap<string,dwarf_derived_probe*> probes_by_module;
411 typedef multimap<string,dwarf_derived_probe*>::iterator p_b_m_iterator;
dc38c0ae
DS
412
413public:
b20febf3
FCE
414 void enroll (dwarf_derived_probe* probe);
415 void emit_module_decls (systemtap_session& s);
416 void emit_module_init (systemtap_session& s);
417 void emit_module_exit (systemtap_session& s);
dc38c0ae
DS
418};
419
420
20c6c071 421// Helper struct to thread through the dwfl callbacks.
2c384610 422struct base_query
20c6c071 423{
c4ce66a1
JS
424 base_query(dwflpp & dw, literal_map_t const & params);
425 base_query(dwflpp & dw, const string & module_val);
2c384610 426 virtual ~base_query() {}
bd2b1e68 427
5227f1ea 428 systemtap_session & sess;
2c384610 429 dwflpp & dw;
5227f1ea 430
bd2b1e68 431 // Parameter extractors.
86bf665e 432 static bool has_null_param(literal_map_t const & params,
888af770 433 string const & k);
86bf665e 434 static bool get_string_param(literal_map_t const & params,
bd2b1e68 435 string const & k, string & v);
86bf665e 436 static bool get_number_param(literal_map_t const & params,
bd2b1e68 437 string const & k, long & v);
86bf665e 438 static bool get_number_param(literal_map_t const & params,
c239d28c 439 string const & k, Dwarf_Addr & v);
b55bc428 440
2c384610
DS
441 // Extracted parameters.
442 bool has_kernel;
91af0778
FCE
443 bool has_module;
444 bool has_process;
2c384610
DS
445 string module_val; // has_kernel => module_val = "kernel"
446
447 virtual void handle_query_module() = 0;
448};
449
450
c4ce66a1
JS
451base_query::base_query(dwflpp & dw, literal_map_t const & params):
452 sess(dw.sess), dw(dw)
2c384610 453{
91af0778 454 has_kernel = has_null_param (params, TOK_KERNEL);
2c384610
DS
455 if (has_kernel)
456 module_val = "kernel";
91af0778
FCE
457
458 has_module = get_string_param (params, TOK_MODULE, module_val);
459 if (has_module)
460 has_process = false;
4baf0e53 461 else
d0a7f5a9
FCE
462 {
463 has_process = get_string_param(params, TOK_PROCESS, module_val);
06aca46a 464 if (has_process)
d0a7f5a9
FCE
465 module_val = find_executable (module_val);
466 }
91af0778
FCE
467
468 assert (has_kernel || has_process || has_module);
2c384610
DS
469}
470
c4ce66a1
JS
471base_query::base_query(dwflpp & dw, const string & module_val)
472 : sess(dw.sess), dw(dw), module_val(module_val)
473{
474 // NB: This uses '/' to distinguish between kernel modules and userspace,
475 // which means that userspace modules won't get any PATH searching.
476 if (module_val.find('/') == string::npos)
477 {
478 has_kernel = (module_val == TOK_KERNEL);
479 has_module = !has_kernel;
480 has_process = false;
481 }
482 else
483 {
484 has_kernel = has_module = false;
485 has_process = true;
486 }
487}
488
2c384610 489bool
86bf665e 490base_query::has_null_param(literal_map_t const & params,
2c384610
DS
491 string const & k)
492{
888af770 493 return derived_probe_builder::has_null_param(params, k);
2c384610
DS
494}
495
496
497bool
86bf665e 498base_query::get_string_param(literal_map_t const & params,
2c384610
DS
499 string const & k, string & v)
500{
501 return derived_probe_builder::get_param (params, k, v);
502}
503
504
505bool
86bf665e 506base_query::get_number_param(literal_map_t const & params,
2c384610
DS
507 string const & k, long & v)
508{
509 int64_t value;
510 bool present = derived_probe_builder::get_param (params, k, value);
511 v = (long) value;
512 return present;
513}
514
515
516bool
86bf665e 517base_query::get_number_param(literal_map_t const & params,
2c384610
DS
518 string const & k, Dwarf_Addr & v)
519{
520 int64_t value;
521 bool present = derived_probe_builder::get_param (params, k, value);
522 v = (Dwarf_Addr) value;
523 return present;
524}
525
2c384610
DS
526struct dwarf_query : public base_query
527{
e1278bd4 528 dwarf_query(probe * base_probe,
2c384610
DS
529 probe_point * base_loc,
530 dwflpp & dw,
86bf665e 531 literal_map_t const & params,
2c384610
DS
532 vector<derived_probe *> & results);
533
c4ce66a1
JS
534 vector<derived_probe *> & results;
535 probe * base_probe;
536 probe_point * base_loc;
537
2c384610 538 virtual void handle_query_module();
5f0a03a6
JK
539 void query_module_dwarf();
540 void query_module_symtab();
2c384610 541
2930abc7
FCE
542 void add_probe_point(string const & funcname,
543 char const * filename,
544 int line,
545 Dwarf_Die *scope_die,
546 Dwarf_Addr addr);
36f9dd1d 547
2930abc7 548 // Extracted parameters.
7a053d3b 549 string function_val;
20c6c071
GH
550
551 bool has_function_str;
552 bool has_statement_str;
553 bool has_function_num;
554 bool has_statement_num;
7a053d3b
RM
555 string statement_str_val;
556 string function_str_val;
c239d28c
GH
557 Dwarf_Addr statement_num_val;
558 Dwarf_Addr function_num_val;
20c6c071 559
b8da0ad1
FCE
560 bool has_call;
561 bool has_inline;
20c6c071
GH
562 bool has_return;
563
c9bad430
DS
564 bool has_maxactive;
565 long maxactive_val;
566
20c6c071
GH
567 bool has_label;
568 string label_val;
569
570 bool has_relative;
571 long relative_val;
572
37ebca01
FCE
573 bool has_absolute;
574
467bea43
SC
575 bool has_mark;
576
5f0a03a6
JK
577 enum dbinfo_reqt dbinfo_reqt;
578 enum dbinfo_reqt assess_dbinfo_reqt();
579
20c6c071
GH
580 function_spec_type parse_function_spec(string & spec);
581 function_spec_type spec_type;
582 string function;
583 string file;
0c8b7d37 584 line_t line_type;
879eb9e9 585 int line[2];
5f0a03a6 586 bool query_done; // Found exact match
20c6c071 587
7e1279ea
FCE
588 set<char const *> filtered_srcfiles;
589
590 // Map official entrypc -> func_info object
86bf665e
TM
591 inline_instance_map_t filtered_inlines;
592 func_info_map_t filtered_functions;
7e1279ea
FCE
593 bool choose_next_line;
594 Dwarf_Addr entrypc_for_next_line;
b55bc428
FCE
595};
596
98afd80e
FCE
597
598struct dwarf_builder: public derived_probe_builder
b55bc428 599{
665e1256 600 map <string,dwflpp*> kern_dw; /* NB: key string could be a wildcard */
7a24d422 601 map <string,dwflpp*> user_dw;
ae2552da 602 dwarf_builder() {}
aa30ccd3 603
ae2552da 604 dwflpp *get_kern_dw(systemtap_session& sess, const string& module)
707bf35e 605 {
ea14cf67
FCE
606 if (kern_dw[module] == 0)
607 kern_dw[module] = new dwflpp(sess, module, true); // might throw
ae2552da 608 return kern_dw[module];
707bf35e
JS
609 }
610
611 dwflpp *get_user_dw(systemtap_session& sess, const string& module)
612 {
ea14cf67
FCE
613 if (user_dw[module] == 0)
614 user_dw[module] = new dwflpp(sess, module, false); // might throw
707bf35e
JS
615 return user_dw[module];
616 }
7a24d422
FCE
617
618 /* NB: not virtual, so can be called from dtor too: */
06aca46a 619 void dwarf_build_no_more (bool verbose)
aa30ccd3 620 {
ae2552da
FCE
621 for (map<string,dwflpp*>::iterator udi = kern_dw.begin();
622 udi != kern_dw.end();
623 udi ++)
aa30ccd3 624 {
7a24d422 625 if (verbose)
ae2552da
FCE
626 clog << "dwarf_builder releasing kernel dwflpp " << udi->first << endl;
627 delete udi->second;
aa30ccd3 628 }
ae2552da 629 kern_dw.erase (kern_dw.begin(), kern_dw.end());
7a24d422
FCE
630
631 for (map<string,dwflpp*>::iterator udi = user_dw.begin();
632 udi != user_dw.end();
633 udi ++)
634 {
635 if (verbose)
636 clog << "dwarf_builder releasing user dwflpp " << udi->first << endl;
637 delete udi->second;
638 }
639 user_dw.erase (user_dw.begin(), user_dw.end());
640 }
641
642 void build_no_more (systemtap_session &s)
643 {
644 dwarf_build_no_more (s.verbose > 3);
aa30ccd3
FCE
645 }
646
e38d6504
RM
647 ~dwarf_builder()
648 {
7a24d422 649 dwarf_build_no_more (false);
c8959a29 650 }
aa30ccd3 651
5227f1ea 652 virtual void build(systemtap_session & sess,
7a053d3b 653 probe * base,
20c6c071 654 probe_point * location,
86bf665e 655 literal_map_t const & parameters,
20c6c071 656 vector<derived_probe *> & finished_results);
b55bc428
FCE
657};
658
5111fc3e 659
e1278bd4 660dwarf_query::dwarf_query(probe * base_probe,
20c6c071
GH
661 probe_point * base_loc,
662 dwflpp & dw,
86bf665e 663 literal_map_t const & params,
20c6c071 664 vector<derived_probe *> & results)
c4ce66a1
JS
665 : base_query(dw, params), results(results),
666 base_probe(base_probe), base_loc(base_loc)
bd2b1e68
GH
667{
668 // Reduce the query to more reasonable semantic values (booleans,
669 // extracted strings, numbers, etc).
bd2b1e68
GH
670 has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
671 has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
672
673 has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
674 has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
675
0f336e95
SC
676 has_label = get_string_param(params, TOK_LABEL, label_val);
677
b8da0ad1
FCE
678 has_call = has_null_param(params, TOK_CALL);
679 has_inline = has_null_param(params, TOK_INLINE);
bd2b1e68 680 has_return = has_null_param(params, TOK_RETURN);
c9bad430 681 has_maxactive = get_number_param(params, TOK_MAXACTIVE, maxactive_val);
37ebca01 682 has_absolute = has_null_param(params, TOK_ABSOLUTE);
467bea43 683 has_mark = false;
37ebca01 684
bd2b1e68
GH
685 if (has_function_str)
686 spec_type = parse_function_spec(function_str_val);
687 else if (has_statement_str)
688 spec_type = parse_function_spec(statement_str_val);
0daad364 689
5f0a03a6
JK
690 dbinfo_reqt = assess_dbinfo_reqt();
691 query_done = false;
0daad364
JS
692}
693
694
440f755a
JS
695func_info_map_t *
696get_filtered_functions(dwarf_query *q)
697{
698 return &q->filtered_functions;
699}
700
701
702inline_instance_map_t *
703get_filtered_inlines(dwarf_query *q)
704{
705 return &q->filtered_inlines;
706}
707
708
709void
710add_label_name(dwarf_query *q, const char *name)
711{
712 // this is a kludge to let the listing mode show labels to the user
713 if (q->sess.listing_mode)
714 q->results.back()->locations[0]->components.push_back
715 (new probe_point::component(TOK_LABEL, new literal_string (name)));
716}
717
718
2c384610 719void
5f0a03a6 720dwarf_query::query_module_dwarf()
2c384610
DS
721{
722 if (has_function_num || has_statement_num)
723 {
724 // If we have module("foo").function(0xbeef) or
725 // module("foo").statement(0xbeef), the address is relative
726 // to the start of the module, so we seek the function
727 // number plus the module's bias.
728
729 Dwarf_Addr addr;
730 if (has_function_num)
731 addr = function_num_val;
732 else
733 addr = statement_num_val;
4baf0e53 734
1f8592d1
MW
735 // Translate to an actual symbol address.
736 addr = dw.literal_addr_to_sym_addr (addr);
737
1adf8ef1
JS
738 Dwarf_Die* cudie = dw.query_cu_containing_address(addr);
739 if (cudie) // address could be wildly out of range
740 query_cu(cudie, this);
2c384610
DS
741 }
742 else
743 {
744 // Otherwise if we have a function("foo") or statement("foo")
745 // specifier, we have to scan over all the CUs looking for
746 // the function(s) in question
747 assert(has_function_str || has_statement_str);
748 dw.iterate_over_cus(&query_cu, this);
749 }
750}
751
5f0a03a6
JK
752static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
753 dwarf_query * q);
754
755void
756dwarf_query::query_module_symtab()
757{
758 // Get the symbol table if it's necessary, sufficient, and not already got.
759 if (dbinfo_reqt == dbr_need_dwarf)
760 return;
761
762 module_info *mi = dw.mod_info;
763 if (dbinfo_reqt == dbr_need_symtab)
764 {
765 if (mi->symtab_status == info_unknown)
766 mi->get_symtab(this);
767 if (mi->symtab_status == info_absent)
768 return;
769 }
770
771 func_info *fi = NULL;
772 symbol_table *sym_table = mi->sym_table;
773
774 if (has_function_str)
775 {
776 // Per dwarf_query::assess_dbinfo_reqt()...
777 assert(spec_type == function_alone);
778 if (dw.name_has_wildcard(function_str_val))
779 {
780 // Until we augment the blacklist sufficently...
781 if (function_str_val.find_first_not_of("*?") == string::npos)
782 {
783 // e.g., kernel.function("*")
784 cerr << "Error: Pattern '"
785 << function_str_val
786 << "' matches every instruction address in the symbol table,"
787 << endl
788 << "some of which aren't even functions."
789 << " Please be more precise."
790 << endl;
791 return;
792 }
2e67a43b 793 symbol_table::iterator_t iter;
1c6b77e5
JS
794 for (iter = sym_table->map_by_addr.begin();
795 iter != sym_table->map_by_addr.end();
2e67a43b 796 ++iter)
5f0a03a6 797 {
1c6b77e5 798 fi = iter->second;
5f0a03a6
JK
799 if (!null_die(&fi->die))
800 continue; // already handled in query_module_dwarf()
801 if (dw.function_name_matches_pattern(fi->name, function_str_val))
802 query_func_info(fi->addr, *fi, this);
803 }
804 }
805 else
806 {
807 fi = sym_table->lookup_symbol(function_str_val);
808 if (fi && null_die(&fi->die))
809 query_func_info(fi->addr, *fi, this);
810 }
811 }
812 else
813 {
814 assert(has_function_num || has_statement_num);
815 // Find the "function" in which the indicated address resides.
816 Dwarf_Addr addr =
817 (has_function_num ? function_num_val : statement_num_val);
818 fi = sym_table->get_func_containing_address(addr);
819 if (!fi)
820 {
83ca3872
MW
821 if (! sess.suppress_warnings)
822 cerr << "Warning: address "
823 << hex << addr << dec
824 << " out of range for module "
825 << dw.module_name;
5f0a03a6
JK
826 return;
827 }
828 if (!null_die(&fi->die))
829 {
830 // addr looks like it's in the compilation unit containing
831 // the indicated function, but query_module_dwarf() didn't
832 // match addr to any compilation unit, so addr must be
833 // above that cu's address range.
83ca3872
MW
834 if (! sess.suppress_warnings)
835 cerr << "Warning: address "
836 << hex << addr << dec
837 << " maps to no known compilation unit in module "
838 << dw.module_name;
5f0a03a6
JK
839 return;
840 }
841 query_func_info(fi->addr, *fi, this);
842 }
843}
844
845void
846dwarf_query::handle_query_module()
847{
1c6b77e5
JS
848 bool report = dbinfo_reqt == dbr_need_dwarf || !sess.consult_symtab;
849 dw.get_module_dwarf(false, report);
850
851 // prebuild the symbol table to resolve aliases
852 dw.mod_info->get_symtab(this);
853
5f0a03a6
JK
854 if (dw.mod_info->dwarf_status == info_present)
855 query_module_dwarf();
1c6b77e5 856
5f0a03a6
JK
857 // Consult the symbol table if we haven't found all we're looking for.
858 // asm functions can show up in the symbol table but not in dwarf.
859 if (sess.consult_symtab && !query_done)
860 query_module_symtab();
861}
862
2c384610 863
bd2b1e68 864function_spec_type
20c6c071 865dwarf_query::parse_function_spec(string & spec)
bd2b1e68
GH
866{
867 string::const_iterator i = spec.begin(), e = spec.end();
7a053d3b 868
bd2b1e68
GH
869 function.clear();
870 file.clear();
879eb9e9
SC
871 line[0] = 0;
872 line[1] = 0;
bd2b1e68
GH
873
874 while (i != e && *i != '@')
875 {
0c8b7d37 876 if (*i == ':' || *i == '+')
bd2b1e68
GH
877 goto bad;
878 function += *i++;
879 }
880
881 if (i == e)
882 {
b0ee93c4 883 if (sess.verbose>2)
7a053d3b
RM
884 clog << "parsed '" << spec
885 << "' -> func '" << function
db22e55f 886 << "'\n";
bd2b1e68
GH
887 return function_alone;
888 }
889
890 if (i++ == e)
891 goto bad;
892
0c8b7d37 893 while (i != e && *i != ':' && *i != '+')
bd2b1e68 894 file += *i++;
41c262f3 895 if (*i == ':')
879eb9e9
SC
896 {
897 if (*(i + 1) == '*')
898 line_type = WILDCARD;
899 else
900 line_type = ABSOLUTE;
901 }
0c8b7d37
SC
902 else if (*i == '+')
903 line_type = RELATIVE;
7a053d3b 904
bd2b1e68
GH
905 if (i == e)
906 {
b0ee93c4 907 if (sess.verbose>2)
7a053d3b
RM
908 clog << "parsed '" << spec
909 << "' -> func '"<< function
910 << "', file '" << file
db22e55f 911 << "'\n";
bd2b1e68
GH
912 return function_and_file;
913 }
914
915 if (i++ == e)
916 goto bad;
917
918 try
919 {
879eb9e9
SC
920 if (line_type != WILDCARD)
921 {
922 string::const_iterator dash = i;
41c262f3 923
879eb9e9
SC
924 while (dash != e && *dash != '-')
925 dash++;
926 if (dash == e)
927 line[0] = line[1] = lex_cast<int>(string(i, e));
928 else
929 {
930 line_type = RANGE;
931 line[0] = lex_cast<int>(string(i, dash));
932 line[1] = lex_cast<int>(string(dash + 1, e));
933 }
934 }
41c262f3 935
b0ee93c4 936 if (sess.verbose>2)
7a053d3b
RM
937 clog << "parsed '" << spec
938 << "' -> func '"<< function
939 << "', file '" << file
db22e55f 940 << "', line " << line << "\n";
bd2b1e68
GH
941 return function_file_and_line;
942 }
943 catch (runtime_error & exn)
944 {
945 goto bad;
946 }
947
948 bad:
7a053d3b 949 throw semantic_error("malformed specification '" + spec + "'",
20c6c071 950 base_probe->tok);
bd2b1e68
GH
951}
952
953
36f9dd1d 954void
b20febf3
FCE
955dwarf_query::add_probe_point(const string& funcname,
956 const char* filename,
36f9dd1d 957 int line,
b20febf3 958 Dwarf_Die* scope_die,
36f9dd1d
FCE
959 Dwarf_Addr addr)
960{
b20febf3 961 string reloc_section; // base section for relocation purposes
27646582 962 Dwarf_Addr reloc_addr; // relocated
b20febf3
FCE
963 string blacklist_section; // linking section for blacklist purposes
964 const string& module = dw.module_name; // "kernel" or other
36f9dd1d 965
37ebca01
FCE
966 assert (! has_absolute); // already handled in dwarf_builder::build()
967
27646582 968 reloc_addr = dw.relocate_address(addr, reloc_section, blacklist_section);
2930abc7 969
7f9f3386
FCE
970 if (sess.verbose > 1)
971 {
b20febf3
FCE
972 clog << "probe " << funcname << "@" << filename << ":" << line;
973 if (string(module) == TOK_KERNEL)
974 clog << " kernel";
91af0778 975 else if (has_module)
b20febf3 976 clog << " module=" << module;
91af0778
FCE
977 else if (has_process)
978 clog << " process=" << module;
b20febf3
FCE
979 if (reloc_section != "") clog << " reloc=" << reloc_section;
980 if (blacklist_section != "") clog << " section=" << blacklist_section;
981 clog << " pc=0x" << hex << addr << dec;
7f9f3386 982 }
4baf0e53 983
27646582
JS
984 bool bad = dw.blacklisted_p (funcname, filename, line, module,
985 blacklist_section, addr, has_return);
b20febf3
FCE
986 if (sess.verbose > 1)
987 clog << endl;
7f9f3386 988
84048984
FCE
989 if (module == TOK_KERNEL)
990 {
991 // PR 4224: adapt to relocatable kernel by subtracting the _stext address here.
992 reloc_addr = addr - sess.sym_stext;
37ebca01 993 reloc_section = "_stext"; // a message to runtime's _stp_module_relocate
84048984
FCE
994 }
995
b20febf3
FCE
996 if (! bad)
997 {
1a0dbc5a 998 sess.unwindsym_modules.insert (module);
6d0f3f0c
FCE
999
1000 if (has_process)
1001 {
1002 results.push_back (new uprobe_derived_probe(funcname, filename, line,
1003 module, 0, reloc_section, addr, reloc_addr,
1004 *this, scope_die));
1005 }
1006 else
1007 {
1008 assert (has_kernel || has_module);
1009 results.push_back (new dwarf_derived_probe(funcname, filename, line,
06aca46a 1010 module, reloc_section, addr, reloc_addr,
6d0f3f0c
FCE
1011 *this, scope_die));
1012 }
b20febf3 1013 }
2930abc7
FCE
1014}
1015
5f0a03a6
JK
1016enum dbinfo_reqt
1017dwarf_query::assess_dbinfo_reqt()
1018{
1019 if (has_absolute)
1020 {
1021 // kernel.statement(NUM).absolute
1022 return dbr_none;
1023 }
1024 if (has_inline)
1025 {
1026 // kernel.function("f").inline or module("m").function("f").inline
1027 return dbr_need_dwarf;
1028 }
1029 if (has_function_str && spec_type == function_alone)
1030 {
1031 // kernel.function("f") or module("m").function("f")
1032 return dbr_need_symtab;
1033 }
1034 if (has_statement_num)
1035 {
1036 // kernel.statement(NUM) or module("m").statement(NUM)
1037 // Technically, all we need is the module offset (or _stext, for
1038 // the kernel). But for that we need either the ELF file or (for
1039 // _stext) the symbol table. In either case, the symbol table
1040 // is available, and that allows us to map the NUM (address)
1041 // to a function, which is goodness.
1042 return dbr_need_symtab;
1043 }
1044 if (has_function_num)
1045 {
1046 // kernel.function(NUM) or module("m").function(NUM)
1047 // Need the symbol table so we can back up from NUM to the
1048 // start of the function.
1049 return dbr_need_symtab;
1050 }
1051 // Symbol table tells us nothing about source files or line numbers.
1052 return dbr_need_dwarf;
1053}
2930abc7
FCE
1054
1055
b8da0ad1
FCE
1056// The critical determining factor when interpreting a pattern
1057// string is, perhaps surprisingly: "presence of a lineno". The
1058// presence of a lineno changes the search strategy completely.
1059//
1060// Compare the two cases:
1061//
1062// 1. {statement,function}(foo@file.c:lineno)
1063// - find the files matching file.c
1064// - in each file, find the functions matching foo
1065// - query the file for line records matching lineno
1066// - iterate over the line records,
1067// - and iterate over the functions,
1068// - if(haspc(function.DIE, line.addr))
1069// - if looking for statements: probe(lineno.addr)
1070// - if looking for functions: probe(function.{entrypc,return,etc.})
1071//
1072// 2. {statement,function}(foo@file.c)
1073// - find the files matching file.c
1074// - in each file, find the functions matching foo
1075// - probe(function.{entrypc,return,etc.})
1076//
1077// Thus the first decision we make is based on the presence of a
1078// lineno, and we enter entirely different sets of callbacks
1079// depending on that decision.
1080//
1081// Note that the first case is a generalization fo the second, in that
1082// we could theoretically search through line records for matching
1083// file names (a "table scan" in rdbms lingo). Luckily, file names
1084// are already cached elsewhere, so we can do an "index scan" as an
1085// optimization.
7e1279ea 1086
bd2b1e68 1087static void
4cd232e4 1088query_statement (string const & func,
20e4a32c 1089 char const * file,
4cd232e4 1090 int line,
bcc12710 1091 Dwarf_Die *scope_die,
20e4a32c 1092 Dwarf_Addr stmt_addr,
4cd232e4 1093 dwarf_query * q)
bd2b1e68 1094{
39bcd429
FCE
1095 try
1096 {
cee35f73 1097 q->add_probe_point(func, file ? file : "",
a9b2f3a5 1098 line, scope_die, stmt_addr);
39bcd429
FCE
1099 }
1100 catch (const semantic_error& e)
1101 {
1102 q->sess.print_error (e);
1103 }
bd2b1e68
GH
1104}
1105
7e1279ea 1106static void
3e961ba6 1107query_inline_instance_info (inline_instance_info & ii,
7e1279ea
FCE
1108 dwarf_query * q)
1109{
b6581717 1110 try
7e1279ea 1111 {
b6581717
GH
1112 if (q->has_return)
1113 {
1114 throw semantic_error ("cannot probe .return of inline function '" + ii.name + "'");
1115 }
1116 else
1117 {
b0ee93c4 1118 if (q->sess.verbose>2)
20e4a32c 1119 clog << "querying entrypc "
3e961ba6 1120 << hex << ii.entrypc << dec
db22e55f 1121 << " of instance of inline '" << ii.name << "'\n";
20e4a32c 1122 query_statement (ii.name, ii.decl_file, ii.decl_line,
3e961ba6 1123 &ii.die, ii.entrypc, q);
b6581717 1124 }
7e1279ea 1125 }
b6581717 1126 catch (semantic_error &e)
7e1279ea 1127 {
b6581717 1128 q->sess.print_error (e);
7e1279ea
FCE
1129 }
1130}
1131
1132static void
1133query_func_info (Dwarf_Addr entrypc,
bcc12710 1134 func_info & fi,
7e1279ea
FCE
1135 dwarf_query * q)
1136{
b6581717 1137 try
7e1279ea 1138 {
b6581717
GH
1139 if (q->has_return)
1140 {
1141 // NB. dwarf_derived_probe::emit_registrations will emit a
1142 // kretprobe based on the entrypc in this case.
20e4a32c 1143 query_statement (fi.name, fi.decl_file, fi.decl_line,
b6581717
GH
1144 &fi.die, entrypc, q);
1145 }
1146 else
1147 {
35dc8b04 1148 if (fi.prologue_end != 0)
44f75386 1149 {
44f75386
FCE
1150 query_statement (fi.name, fi.decl_file, fi.decl_line,
1151 &fi.die, fi.prologue_end, q);
1152 }
1153 else
1154 {
1155 query_statement (fi.name, fi.decl_file, fi.decl_line,
1156 &fi.die, entrypc, q);
1157 }
b6581717 1158 }
7e1279ea 1159 }
b6581717 1160 catch (semantic_error &e)
7e1279ea 1161 {
b6581717 1162 q->sess.print_error (e);
7e1279ea
FCE
1163 }
1164}
1165
1166
bd4b874d
SC
1167static void
1168query_srcfile_label (const dwarf_line_t& line, void * arg)
1169{
1170 dwarf_query * q = static_cast<dwarf_query *>(arg);
1171
1172 Dwarf_Addr addr = line.addr();
1173
1174 for (func_info_map_t::iterator i = q->filtered_functions.begin();
1175 i != q->filtered_functions.end(); ++i)
1176 if (q->dw.die_has_pc (i->die, addr))
440f755a
JS
1177 q->dw.iterate_over_labels (&i->die, q->label_val.c_str(), q->function.c_str(),
1178 q, query_statement);
bd4b874d
SC
1179}
1180
7e1279ea 1181static void
86bf665e 1182query_srcfile_line (const dwarf_line_t& line, void * arg)
7e1279ea
FCE
1183{
1184 dwarf_query * q = static_cast<dwarf_query *>(arg);
1185
86bf665e 1186 Dwarf_Addr addr = line.addr();
4cd232e4 1187
86bf665e 1188 int lineno = line.lineno();
847bf07f 1189
86bf665e 1190 for (func_info_map_t::iterator i = q->filtered_functions.begin();
7e1279ea
FCE
1191 i != q->filtered_functions.end(); ++i)
1192 {
3e961ba6 1193 if (q->dw.die_has_pc (i->die, addr))
7e1279ea 1194 {
b0ee93c4 1195 if (q->sess.verbose>3)
db22e55f 1196 clog << "function DIE lands on srcfile\n";
4cd232e4 1197 if (q->has_statement_str)
3e961ba6 1198 query_statement (i->name, i->decl_file,
847bf07f 1199 lineno, // NB: not q->line !
3e961ba6 1200 &(i->die), addr, q);
4cd232e4 1201 else
3e961ba6 1202 query_func_info (i->entrypc, *i, q);
7e1279ea 1203 }
20e4a32c
RM
1204 }
1205
86bf665e 1206 for (inline_instance_map_t::iterator i
897820ca
GH
1207 = q->filtered_inlines.begin();
1208 i != q->filtered_inlines.end(); ++i)
1209 {
3e961ba6 1210 if (q->dw.die_has_pc (i->die, addr))
7e1279ea 1211 {
b0ee93c4 1212 if (q->sess.verbose>3)
db22e55f 1213 clog << "inline instance DIE lands on srcfile\n";
897820ca 1214 if (q->has_statement_str)
3e961ba6
JB
1215 query_statement (i->name, i->decl_file,
1216 q->line[0], &(i->die), addr, q);
897820ca 1217 else
3e961ba6 1218 query_inline_instance_info (*i, q);
897820ca 1219 }
20e4a32c 1220 }
7e1279ea
FCE
1221}
1222
1223
4fa7b22b 1224static int
7e1279ea 1225query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
4fa7b22b
GH
1226{
1227 dwarf_query * q = static_cast<dwarf_query *>(arg);
7e1279ea 1228 assert (!q->has_statement_num);
bd2b1e68 1229
39bcd429 1230 try
7a053d3b 1231 {
b0ee93c4 1232 if (q->sess.verbose>2)
db22e55f 1233 clog << "examining inline instance of " << q->dw.function_name << "\n";
7e1279ea 1234
4baf0e53 1235 if ((q->has_function_str && ! q->has_call)
b8da0ad1 1236 || q->has_statement_str)
7e1279ea 1237 {
b0ee93c4 1238 if (q->sess.verbose>2)
db22e55f
FCE
1239 clog << "selected inline instance of " << q->dw.function_name
1240 << "\n";
7e1279ea
FCE
1241
1242 Dwarf_Addr entrypc;
1243 if (q->dw.die_entrypc (die, &entrypc))
1244 {
1245 inline_instance_info inl;
1246 inl.die = *die;
1247 inl.name = q->dw.function_name;
3e961ba6 1248 inl.entrypc = entrypc;
4cd232e4
GH
1249 q->dw.function_file (&inl.decl_file);
1250 q->dw.function_line (&inl.decl_line);
3e961ba6 1251 q->filtered_inlines.push_back(inl);
7e1279ea
FCE
1252 }
1253 }
1254 return DWARF_CB_OK;
1255 }
1256 catch (const semantic_error& e)
1257 {
1258 q->sess.print_error (e);
1259 return DWARF_CB_ABORT;
1260 }
1261}
bb788f9f 1262
7e1279ea 1263static int
2da9cedb 1264query_dwarf_func (Dwarf_Die * func, base_query * bq)
7e1279ea 1265{
2da9cedb 1266 dwarf_query * q = static_cast<dwarf_query *>(bq);
bb788f9f 1267
7e1279ea
FCE
1268 try
1269 {
7e1279ea
FCE
1270 q->dw.focus_on_function (func);
1271
20e4a32c 1272 if (q->dw.func_is_inline ()
b8da0ad1 1273 && (! q->has_call) && (! q->has_return)
1c6b77e5 1274 && (q->has_statement_str || q->has_function_str))
7e1279ea 1275 {
b0ee93c4 1276 if (q->sess.verbose>3)
db22e55f
FCE
1277 clog << "checking instances of inline " << q->dw.function_name
1278 << "\n";
2da9cedb 1279 q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, q);
275f40a6
FCE
1280
1281 if (q->dw.function_name_final_match (q->function))
1282 return DWARF_CB_ABORT;
7e1279ea 1283 }
396afcee 1284 else if (!q->dw.func_is_inline () && (! q->has_inline))
20e4a32c 1285 {
7e1279ea
FCE
1286 bool record_this_function = false;
1287
1c6b77e5 1288 if (q->has_statement_str || q->has_function_str)
7e1279ea
FCE
1289 {
1290 record_this_function = true;
1291 }
e4c58386 1292 else if (q->has_function_num || q->has_statement_num)
7e1279ea 1293 {
e4c58386 1294 Dwarf_Addr query_addr =
9b692b91
SC
1295 (q->has_function_num ? q->function_num_val :
1296 q->has_statement_num ? q->statement_num_val :
1297 (assert(0) , 0));
7e1279ea
FCE
1298 Dwarf_Die d;
1299 q->dw.function_die (&d);
20e4a32c 1300
1f8592d1
MW
1301 // Translate literal address to symbol address, then
1302 // compensate for dw bias.
1303 query_addr = q->dw.literal_addr_to_sym_addr(query_addr);
1304 query_addr -= q->dw.module_bias;
1305
86bf665e 1306 if (q->dw.die_has_pc (d, query_addr))
7e1279ea
FCE
1307 record_this_function = true;
1308 }
1309
1310 if (record_this_function)
1311 {
b0ee93c4 1312 if (q->sess.verbose>2)
db22e55f 1313 clog << "selected function " << q->dw.function_name << "\n";
7e1279ea 1314
e4c58386
FCE
1315 func_info func;
1316 q->dw.function_die (&func.die);
1317 func.name = q->dw.function_name;
1318 q->dw.function_file (&func.decl_file);
1319 q->dw.function_line (&func.decl_line);
1320
1321 if (q->has_function_num || q->has_function_str || q->has_statement_str)
1322 {
1323 Dwarf_Addr entrypc;
1324 if (q->dw.function_entrypc (&entrypc))
3e961ba6
JB
1325 {
1326 func.entrypc = entrypc;
1327 q->filtered_functions.push_back (func);
1328 }
e4c58386 1329 else
552fdd9f
JB
1330 /* this function just be fully inlined, just ignore it */
1331 return DWARF_CB_OK;
e4c58386
FCE
1332 }
1333 else if (q->has_statement_num)
1334 {
3e961ba6 1335 func.entrypc = q->statement_num_val;
1f8592d1
MW
1336
1337 // Translate literal address to symbol address, then
1338 // compensate for dw bias (will be used for query dw funcs).
1339 func.entrypc = q->dw.literal_addr_to_sym_addr(func.entrypc);
1340 func.entrypc -= q->dw.module_bias;
1341
3e961ba6 1342 q->filtered_functions.push_back (func);
275f40a6
FCE
1343 if (q->dw.function_name_final_match (q->function))
1344 return DWARF_CB_ABORT;
e4c58386
FCE
1345 }
1346 else
1347 assert(0);
1348
1349 if (q->dw.function_name_final_match (q->function))
1350 return DWARF_CB_ABORT;
7e1279ea
FCE
1351 }
1352 }
39bcd429 1353 return DWARF_CB_OK;
bd2b1e68 1354 }
39bcd429 1355 catch (const semantic_error& e)
bd2b1e68 1356 {
39bcd429
FCE
1357 q->sess.print_error (e);
1358 return DWARF_CB_ABORT;
bd2b1e68 1359 }
bd2b1e68
GH
1360}
1361
1362static int
1363query_cu (Dwarf_Die * cudie, void * arg)
1364{
20c6c071 1365 dwarf_query * q = static_cast<dwarf_query *>(arg);
49abf162 1366 if (pending_interrupts) return DWARF_CB_ABORT;
7a053d3b 1367
39bcd429 1368 try
bd2b1e68 1369 {
7e1279ea 1370 q->dw.focus_on_cu (cudie);
b5d77020 1371
b0ee93c4 1372 if (false && q->sess.verbose>2)
b5d77020 1373 clog << "focused on CU '" << q->dw.cu_name
db22e55f 1374 << "', in module '" << q->dw.module_name << "'\n";
d9b516ca 1375
e4c58386 1376 if (q->has_statement_str || q->has_statement_num
54efe513 1377 || q->has_function_str || q->has_function_num)
7e1279ea
FCE
1378 {
1379 q->filtered_srcfiles.clear();
1380 q->filtered_functions.clear();
1381 q->filtered_inlines.clear();
1382
1383 // In this path, we find "abstract functions", record
1384 // information about them, and then (depending on lineno
1385 // matching) possibly emit one or more of the function's
1386 // associated addresses. Unfortunately the control of this
1387 // cannot easily be turned inside out.
1388
b8da0ad1 1389 if ((q->has_statement_str || q->has_function_str)
7e1279ea
FCE
1390 && (q->spec_type != function_alone))
1391 {
1392 // If we have a pattern string with a filename, we need
1393 // to elaborate the srcfile mask in question first.
1394 q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
1395
1396 // If we have a file pattern and *no* srcfile matches, there's
1397 // no need to look further into this CU, so skip.
1398 if (q->filtered_srcfiles.empty())
1399 return DWARF_CB_OK;
1400 }
86bf665e
TM
1401 // Verify that a raw address matches the beginning of a
1402 // statement. This is a somewhat lame check that the address
467bea43
SC
1403 // is at the start of an assembly instruction. Mark probes are in the
1404 // middle of a macro and thus not strictly at a statement beginning.
6a35d102 1405 // Guru mode may override this check.
467bea43 1406 if (q->has_statement_num && ! q->has_mark)
86bf665e
TM
1407 {
1408 Dwarf_Addr queryaddr = q->statement_num_val;
1409 dwarf_line_t address_line(dwarf_getsrc_die(cudie, queryaddr));
1410 Dwarf_Addr lineaddr = 0;
1411 if (address_line)
1412 lineaddr = address_line.addr();
1413 if (!address_line || lineaddr != queryaddr)
1414 {
1415 stringstream msg;
1416 msg << "address 0x" << hex << queryaddr
1b1b4ceb 1417 << " does not match the beginning of a statement";
4116c576
MW
1418 if (address_line)
1419 msg << " (try 0x" << hex << lineaddr << ")";
5c5099fa
MW
1420 else
1421 msg << " (no line info found for '" << q->dw.cu_name
1422 << "', in module '" << q->dw.module_name << "')";
6a35d102
MW
1423 if (! q->sess.guru_mode)
1424 throw semantic_error(msg.str());
1425 else if (! q->sess.suppress_warnings)
1426 q->sess.print_warning(msg.str());
86bf665e
TM
1427 }
1428 }
7e1279ea
FCE
1429 // Pick up [entrypc, name, DIE] tuples for all the functions
1430 // matching the query, and fill in the prologue endings of them
1431 // all in a single pass.
2da9cedb
JS
1432 int rc = q->dw.iterate_over_functions (query_dwarf_func, q,
1433 q->function,
1434 q->has_statement_num);
5f0a03a6
JK
1435 if (rc != DWARF_CB_OK)
1436 q->query_done = true;
44f75386 1437
35dc8b04 1438 if ((q->sess.prologue_searching || q->has_process) // PR 6871
e4c58386 1439 && !q->has_statement_str && !q->has_statement_num) // PR 2608
44f75386
FCE
1440 if (! q->filtered_functions.empty())
1441 q->dw.resolve_prologue_endings (q->filtered_functions);
7e1279ea 1442
bd4b874d
SC
1443 if (q->has_label)
1444 {
1445 if (q->line[0] == 0) // No line number specified
440f755a
JS
1446 q->dw.iterate_over_labels (q->dw.cu, q->label_val.c_str(), q->function.c_str(),
1447 q, query_statement);
bd4b874d
SC
1448 else
1449 for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
1450 i != q->filtered_srcfiles.end(); ++i)
1451 q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
1452 q->line_type, query_srcfile_label, q);
1453 }
1454 else if ((q->has_statement_str || q->has_function_str)
7e1279ea
FCE
1455 && (q->spec_type == function_file_and_line))
1456 {
1457 // If we have a pattern string with target *line*, we
20e4a32c 1458 // have to look at lines in all the matched srcfiles.
7e1279ea
FCE
1459 for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
1460 i != q->filtered_srcfiles.end(); ++i)
897820ca 1461 q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
0c8b7d37 1462 q->line_type, query_srcfile_line, q);
7e1279ea
FCE
1463 }
1464 else
1465 {
e4c58386 1466 // Otherwise, simply probe all resolved functions.
86bf665e 1467 for (func_info_map_t::iterator i = q->filtered_functions.begin();
e4c58386 1468 i != q->filtered_functions.end(); ++i)
3e961ba6 1469 query_func_info (i->entrypc, *i, q);
e4c58386
FCE
1470
1471 // And all inline instances (if we're not excluding inlines with ".call")
1472 if (! q->has_call)
86bf665e 1473 for (inline_instance_map_t::iterator i
54efe513 1474 = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
3e961ba6 1475 query_inline_instance_info (*i, q);
7e1279ea
FCE
1476 }
1477 }
39bcd429
FCE
1478 else
1479 {
e4c58386
FCE
1480 // Before PR 5787, we used to have this:
1481#if 0
7e1279ea
FCE
1482 // Otherwise we have a statement number, and we can just
1483 // query it directly within this module.
7e1279ea
FCE
1484 assert (q->has_statement_num);
1485 Dwarf_Addr query_addr = q->statement_num_val;
b8da0ad1 1486 query_addr = q->dw.module_address_to_global(query_addr);
7e1279ea 1487
bcc12710 1488 query_statement ("", "", -1, NULL, query_addr, q);
e4c58386
FCE
1489#endif
1490 // But now, we traverse CUs/functions even for
1491 // statement_num's, for blacklist sensitivity and $var
1492 // resolution purposes.
1493
1494 assert (0); // NOTREACHED
39bcd429
FCE
1495 }
1496 return DWARF_CB_OK;
bd2b1e68 1497 }
39bcd429 1498 catch (const semantic_error& e)
bd2b1e68 1499 {
39bcd429
FCE
1500 q->sess.print_error (e);
1501 return DWARF_CB_ABORT;
bd2b1e68 1502 }
bd2b1e68
GH
1503}
1504
0ce64fb8 1505
5f0a03a6
JK
1506static void
1507validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
1508{
1509 // Validate the machine code in this elf file against the
1510 // session machine. This is important, in case the wrong kind
1511 // of debuginfo is being automagically processed by elfutils.
1512 // While we can tell i686 apart from x86-64, unfortunately
1513 // we can't help confusing i586 vs i686 (both EM_386).
1514
1515 Dwarf_Addr bias;
1516 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
1517 // because dwfl_module_getelf can force costly section relocations
1518 // we don't really need, while either will do for this purpose.
1519 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
1520 ?: dwfl_module_getelf (mod, &bias));
1521
1522 GElf_Ehdr ehdr_mem;
1523 GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
86bf665e 1524 if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
5f0a03a6
JK
1525 int elf_machine = em->e_machine;
1526 const char* debug_filename = "";
1527 const char* main_filename = "";
1528 (void) dwfl_module_info (mod, NULL, NULL,
1529 NULL, NULL, NULL,
1530 & main_filename,
1531 & debug_filename);
1532 const string& sess_machine = q->sess.architecture;
756c9462
FCE
1533
1534 string expect_machine; // to match sess.machine (i.e., kernel machine)
1535 string expect_machine2;
5f0a03a6
JK
1536
1537 switch (elf_machine)
1538 {
756c9462
FCE
1539 // x86 and ppc are bi-architecture; a 64-bit kernel
1540 // can normally run either 32-bit or 64-bit *userspace*.
1541 case EM_386:
1542 expect_machine = "i?86";
1543 if (! q->has_process) break; // 32-bit kernel/module
1544 /* FALLSTHROUGH */
1545 case EM_X86_64:
1546 expect_machine2 = "x86_64";
1547 break;
1548 case EM_PPC:
1549 expect_machine = "ppc";
1550 if (! q->has_process) break; // 32-bit kernel/module
1551 /* FALLSTHROUGH */
1552 case EM_PPC64:
1553 expect_machine2 = "ppc64";
1554 break;
5f0a03a6
JK
1555 case EM_S390: expect_machine = "s390x"; break;
1556 case EM_IA_64: expect_machine = "ia64"; break;
1557 case EM_ARM: expect_machine = "armv*"; break;
1558 // XXX: fill in some more of these
1559 default: expect_machine = "?"; break;
1560 }
1561
1562 if (! debug_filename) debug_filename = main_filename;
1563 if (! debug_filename) debug_filename = name;
1564
756c9462
FCE
1565 if (fnmatch (expect_machine.c_str(), sess_machine.c_str(), 0) != 0 &&
1566 fnmatch (expect_machine2.c_str(), sess_machine.c_str(), 0) != 0)
5f0a03a6
JK
1567 {
1568 stringstream msg;
756c9462
FCE
1569 msg << "ELF machine " << expect_machine << "|" << expect_machine2
1570 << " (code " << elf_machine
5f0a03a6
JK
1571 << ") mismatch with target " << sess_machine
1572 << " in '" << debug_filename << "'";
1573 throw semantic_error(msg.str ());
1574 }
1575
1576 if (q->sess.verbose>2)
1577 clog << "focused on module '" << q->dw.module_name
1578 << " = [0x" << hex << q->dw.module_start
1579 << "-0x" << q->dw.module_end
1580 << ", bias 0x" << q->dw.module_bias << "]" << dec
1581 << " file " << debug_filename
756c9462 1582 << " ELF machine " << expect_machine << "|" << expect_machine2
5f0a03a6
JK
1583 << " (code " << elf_machine << ")"
1584 << "\n";
1585}
1d3a40b6 1586
91af0778
FCE
1587
1588
1589static Dwarf_Addr
1590lookup_symbol_address (Dwfl_Module *m, const char* wanted)
1591{
1592 int syments = dwfl_module_getsymtab(m);
1593 assert(syments);
1594 for (int i = 1; i < syments; ++i)
1595 {
1596 GElf_Sym sym;
1597 const char *name = dwfl_module_getsym(m, i, &sym, NULL);
1598 if (name != NULL && strcmp(name, wanted) == 0)
1599 return sym.st_value;
1600 }
1601
1602 return 0;
1603}
1604
1605
1606
bd2b1e68 1607static int
b8da0ad1 1608query_module (Dwfl_Module *mod,
91af0778 1609 void **,
b8da0ad1 1610 const char *name,
6f4c1275 1611 Dwarf_Addr addr,
b8da0ad1 1612 void *arg)
bd2b1e68 1613{
91af0778 1614 base_query *q = static_cast<base_query *>(arg);
bd2b1e68 1615
39bcd429 1616 try
e38d6504 1617 {
91af0778
FCE
1618 module_info* mi = q->sess.module_cache->cache[name];
1619 if (mi == 0)
1620 {
1621 mi = q->sess.module_cache->cache[name] = new module_info(name);
1622
6f4c1275
FCE
1623 mi->mod = mod;
1624 mi->addr = addr;
91af0778 1625
6f4c1275
FCE
1626 const char* debug_filename = "";
1627 const char* main_filename = "";
1628 (void) dwfl_module_info (mod, NULL, NULL,
1629 NULL, NULL, NULL,
1630 & main_filename,
1631 & debug_filename);
1632
1633 if (q->sess.ignore_vmlinux && name == TOK_KERNEL)
91af0778
FCE
1634 {
1635 // report_kernel() in elfutils found vmlinux, but pretend it didn't.
1636 // Given a non-null path, returning 1 means keep reporting modules.
1637 mi->dwarf_status = info_absent;
1638 }
6f4c1275 1639 else if (debug_filename || main_filename)
91af0778 1640 {
6f4c1275
FCE
1641 mi->elf_path = debug_filename ?: main_filename;
1642 }
1643 else if (name == TOK_KERNEL)
1644 {
1645 mi->dwarf_status = info_absent;
91af0778 1646 }
91af0778
FCE
1647 }
1648 // OK, enough of that module_info caching business.
1649
5f0a03a6 1650 q->dw.focus_on_module(mod, mi);
d9b516ca 1651
39bcd429
FCE
1652 // If we have enough information in the pattern to skip a module and
1653 // the module does not match that information, return early.
b8da0ad1 1654 if (!q->dw.module_name_matches(q->module_val))
0e14e079 1655 return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
0cbbf9d1
FCE
1656
1657 // Don't allow module("*kernel*") type expressions to match the
1658 // elfutils module "kernel", which we refer to in the probe
1659 // point syntax exclusively as "kernel.*".
1660 if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel)
0e14e079 1661 return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
b5d77020 1662
5f0a03a6
JK
1663 if (mod)
1664 validate_module_elf(mod, name, q);
1665 else
91af0778
FCE
1666 assert(q->has_kernel); // and no vmlinux to examine
1667
1668 if (q->sess.verbose>2)
1669 cerr << "focused on module '" << q->dw.module_name << "'\n";
1670
1671
1672 // Collect a few kernel addresses. XXX: these belong better
1673 // to the sess.module_info["kernel"] struct.
1674 if (q->dw.module_name == TOK_KERNEL)
c931ec8a 1675 {
91af0778
FCE
1676 if (! q->sess.sym_kprobes_text_start)
1677 q->sess.sym_kprobes_text_start = lookup_symbol_address (mod, "__kprobes_text_start");
1678 if (! q->sess.sym_kprobes_text_end)
1679 q->sess.sym_kprobes_text_end = lookup_symbol_address (mod, "__kprobes_text_end");
1680 if (! q->sess.sym_stext)
1681 q->sess.sym_stext = lookup_symbol_address (mod, "_stext");
c931ec8a
FCE
1682 }
1683
91af0778 1684 // Finally, search the module for matches of the probe point.
2c384610 1685 q->handle_query_module();
bb788f9f 1686
91af0778 1687
b8da0ad1 1688 // If we know that there will be no more matches, abort early.
0e14e079 1689 if (q->dw.module_name_final_match(q->module_val) || pending_interrupts)
b8da0ad1
FCE
1690 return DWARF_CB_ABORT;
1691 else
1692 return DWARF_CB_OK;
7a053d3b 1693 }
39bcd429 1694 catch (const semantic_error& e)
bd2b1e68 1695 {
39bcd429
FCE
1696 q->sess.print_error (e);
1697 return DWARF_CB_ABORT;
bd2b1e68 1698 }
bd2b1e68
GH
1699}
1700
35d4ab18 1701
de688825 1702struct dwarf_var_expanding_visitor: public var_expanding_visitor
35d4ab18 1703{
77de5e9e 1704 dwarf_query & q;
bcc12710 1705 Dwarf_Die *scope_die;
77de5e9e 1706 Dwarf_Addr addr;
8c819921 1707 block *add_block;
8fc05e57 1708 probe *add_probe;
cd5b28b2 1709 std::map<std::string, symbol *> return_ts_map;
b95e2b79 1710 bool visited;
77de5e9e 1711
de688825 1712 dwarf_var_expanding_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
b95e2b79 1713 q(q), scope_die(sd), addr(a), add_block(NULL), add_probe(NULL), visited(false) {}
a7999c82
JS
1714 void visit_target_symbol_saved_return (target_symbol* e);
1715 void visit_target_symbol_context (target_symbol* e);
d7f3e0c5 1716 void visit_target_symbol (target_symbol* e);
c24447be 1717 void visit_cast_op (cast_op* e);
77de5e9e
GH
1718};
1719
1720
de688825 1721unsigned var_expanding_visitor::tick = 0;
77de5e9e 1722
77de5e9e 1723void
de688825 1724var_expanding_visitor::visit_assignment (assignment* e)
77de5e9e 1725{
e57b735a
GH
1726 // Our job would normally be to require() the left and right sides
1727 // into a new assignment. What we're doing is slightly trickier:
1728 // we're pushing a functioncall** onto a stack, and if our left
1729 // child sets the functioncall* for that value, we're going to
1730 // assume our left child was a target symbol -- transformed into a
1731 // set_target_foo(value) call, and it wants to take our right child
1732 // as the argument "value".
1733 //
1734 // This is why some people claim that languages with
1735 // constructor-decomposing case expressions have a leg up on
1736 // visitors.
1737
1738 functioncall *fcall = NULL;
1739 expression *new_left, *new_right;
d9b516ca 1740
e57b735a 1741 target_symbol_setter_functioncalls.push (&fcall);
4ed05b15 1742 new_left = require (e->left);
e57b735a 1743 target_symbol_setter_functioncalls.pop ();
4ed05b15 1744 new_right = require (e->right);
e57b735a
GH
1745
1746 if (fcall != NULL)
77de5e9e 1747 {
e57b735a
GH
1748 // Our left child is informing us that it was a target variable
1749 // and it has been replaced with a set_target_foo() function
1750 // call; we are going to provide that function call -- with the
1751 // right child spliced in as sole argument -- in place of
de688825 1752 // ourselves, in the var expansion we're in the middle of making.
e57b735a
GH
1753
1754 // FIXME: for the time being, we only support plan $foo = bar,
1755 // not += or any other op= variant. This is fixable, but a bit
1756 // ugly.
1757 if (e->op != "=")
1758 throw semantic_error ("Operator-assign expressions on target "
1759 "variables not implemented", e->tok);
1760
1761 assert (new_left == fcall);
1762 fcall->args.push_back (new_right);
4ed05b15 1763 provide (fcall);
77de5e9e 1764 }
e57b735a
GH
1765 else
1766 {
de688825
JS
1767 e->left = new_left;
1768 e->right = new_right;
1769 provide (e);
e57b735a
GH
1770 }
1771}
d9b516ca 1772
d7f3e0c5 1773
e57b735a 1774void
a7999c82 1775dwarf_var_expanding_visitor::visit_target_symbol_saved_return (target_symbol* e)
e57b735a 1776{
a7999c82
JS
1777 // Get the full name of the target symbol.
1778 stringstream ts_name_stream;
1779 e->print(ts_name_stream);
1780 string ts_name = ts_name_stream.str();
1781
1782 // Check and make sure we haven't already seen this target
1783 // variable in this return probe. If we have, just return our
1784 // last replacement.
1785 map<string, symbol *>::iterator i = return_ts_map.find(ts_name);
1786 if (i != return_ts_map.end())
85ecf79a 1787 {
a7999c82
JS
1788 provide (i->second);
1789 return;
1790 }
85ecf79a 1791
a7999c82
JS
1792 // We've got to do several things here to handle target
1793 // variables in return probes.
85ecf79a 1794
a7999c82
JS
1795 // (1) Synthesize two global arrays. One is the cache of the
1796 // target variable and the other contains a thread specific
1797 // nesting level counter. The arrays will look like
1798 // this:
1799 //
1800 // _dwarf_tvar_{name}_{num}
1801 // _dwarf_tvar_{name}_{num}_ctr
1802
1803 string aname = (string("_dwarf_tvar_")
1804 + e->base_name.substr(1)
1805 + "_" + lex_cast<string>(tick++));
1806 vardecl* vd = new vardecl;
1807 vd->name = aname;
1808 vd->tok = e->tok;
1809 q.sess.globals.push_back (vd);
1810
1811 string ctrname = aname + "_ctr";
1812 vd = new vardecl;
1813 vd->name = ctrname;
1814 vd->tok = e->tok;
1815 q.sess.globals.push_back (vd);
1816
1817 // (2) Create a new code block we're going to insert at the
1818 // beginning of this probe to get the cached value into a
1819 // temporary variable. We'll replace the target variable
1820 // reference with the temporary variable reference. The code
1821 // will look like this:
1822 //
1823 // _dwarf_tvar_tid = tid()
1824 // _dwarf_tvar_{name}_{num}_tmp
1825 // = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
1826 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
1827 // delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
1828 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
1829 // if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
1830 // delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
1831
1832 // (2a) Synthesize the tid temporary expression, which will look
1833 // like this:
1834 //
1835 // _dwarf_tvar_tid = tid()
1836 symbol* tidsym = new symbol;
1837 tidsym->name = string("_dwarf_tvar_tid");
1838 tidsym->tok = e->tok;
85ecf79a 1839
a7999c82
JS
1840 if (add_block == NULL)
1841 {
1842 add_block = new block;
1843 add_block->tok = e->tok;
8c819921 1844
a7999c82
JS
1845 // Synthesize a functioncall to grab the thread id.
1846 functioncall* fc = new functioncall;
1847 fc->tok = e->tok;
1848 fc->function = string("tid");
8c819921 1849
a7999c82 1850 // Assign the tid to '_dwarf_tvar_tid'.
8c819921
DS
1851 assignment* a = new assignment;
1852 a->tok = e->tok;
1853 a->op = "=";
a7999c82
JS
1854 a->left = tidsym;
1855 a->right = fc;
8c819921
DS
1856
1857 expr_statement* es = new expr_statement;
1858 es->tok = e->tok;
1859 es->value = a;
8c819921 1860 add_block->statements.push_back (es);
a7999c82 1861 }
8c819921 1862
a7999c82
JS
1863 // (2b) Synthesize an array reference and assign it to a
1864 // temporary variable (that we'll use as replacement for the
1865 // target variable reference). It will look like this:
1866 //
1867 // _dwarf_tvar_{name}_{num}_tmp
1868 // = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
1869 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
1870
1871 arrayindex* ai_tvar_base = new arrayindex;
1872 ai_tvar_base->tok = e->tok;
1873
1874 symbol* sym = new symbol;
1875 sym->name = aname;
1876 sym->tok = e->tok;
1877 ai_tvar_base->base = sym;
1878
1879 ai_tvar_base->indexes.push_back(tidsym);
1880
1881 // We need to create a copy of the array index in its current
1882 // state so we can have 2 variants of it (the original and one
1883 // that post-decrements the second index).
1884 arrayindex* ai_tvar = new arrayindex;
1885 arrayindex* ai_tvar_postdec = new arrayindex;
1886 *ai_tvar = *ai_tvar_base;
1887 *ai_tvar_postdec = *ai_tvar_base;
1888
1889 // Synthesize the
1890 // "_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]" used as the
1891 // second index into the array.
1892 arrayindex* ai_ctr = new arrayindex;
1893 ai_ctr->tok = e->tok;
1894
1895 sym = new symbol;
1896 sym->name = ctrname;
1897 sym->tok = e->tok;
1898 ai_ctr->base = sym;
1899 ai_ctr->indexes.push_back(tidsym);
1900 ai_tvar->indexes.push_back(ai_ctr);
1901
1902 symbol* tmpsym = new symbol;
1903 tmpsym->name = aname + "_tmp";
1904 tmpsym->tok = e->tok;
1905
1906 assignment* a = new assignment;
1907 a->tok = e->tok;
1908 a->op = "=";
1909 a->left = tmpsym;
1910 a->right = ai_tvar;
1911
1912 expr_statement* es = new expr_statement;
1913 es->tok = e->tok;
1914 es->value = a;
1915
1916 add_block->statements.push_back (es);
1917
1918 // (2c) Add a post-decrement to the second array index and
1919 // delete the array value. It will look like this:
1920 //
1921 // delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
1922 // _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
1923
1924 post_crement* pc = new post_crement;
1925 pc->tok = e->tok;
1926 pc->op = "--";
1927 pc->operand = ai_ctr;
1928 ai_tvar_postdec->indexes.push_back(pc);
1929
1930 delete_statement* ds = new delete_statement;
1931 ds->tok = e->tok;
1932 ds->value = ai_tvar_postdec;
1933
1934 add_block->statements.push_back (ds);
1935
1936 // (2d) Delete the counter value if it is 0. It will look like
1937 // this:
1938 // if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
1939 // delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
1940
1941 ds = new delete_statement;
1942 ds->tok = e->tok;
1943 ds->value = ai_ctr;
1944
1945 unary_expression *ue = new unary_expression;
1946 ue->tok = e->tok;
1947 ue->op = "!";
1948 ue->operand = ai_ctr;
1949
1950 if_statement *ifs = new if_statement;
1951 ifs->tok = e->tok;
1952 ifs->condition = ue;
1953 ifs->thenblock = ds;
1954 ifs->elseblock = NULL;
1955
1956 add_block->statements.push_back (ifs);
1957
1958 // (3) We need an entry probe that saves the value for us in the
1959 // global array we created. Create the entry probe, which will
1960 // look like this:
1961 //
1962 // probe kernel.function("{function}") {
1963 // _dwarf_tvar_tid = tid()
1964 // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
1965 // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
1966 // = ${param}
1967 // }
1968
1969 if (add_probe == NULL)
1970 {
1971 add_probe = new probe;
1972 add_probe->tok = e->tok;
1973
1974 // We need the name of the current probe point, minus the
1975 // ".return" (or anything after it, such as ".maxactive(N)").
1976 // Create a new probe point, copying all the components,
1977 // stopping when we see the ".return" component.
1978 probe_point* pp = new probe_point;
1979 for (unsigned c = 0; c < q.base_loc->components.size(); c++)
85ecf79a 1980 {
a7999c82
JS
1981 if (q.base_loc->components[c]->functor == "return")
1982 break;
1983 else
1984 pp->components.push_back(q.base_loc->components[c]);
1985 }
1986 pp->tok = e->tok;
1987 pp->optional = q.base_loc->optional;
1988 add_probe->locations.push_back(pp);
8fc05e57 1989
a7999c82
JS
1990 add_probe->body = new block;
1991 add_probe->body->tok = e->tok;
4baf0e53 1992
a7999c82
JS
1993 // Synthesize a functioncall to grab the thread id.
1994 functioncall* fc = new functioncall;
1995 fc->tok = e->tok;
1996 fc->function = string("tid");
4baf0e53 1997
a7999c82
JS
1998 // Assign the tid to '_dwarf_tvar_tid'.
1999 assignment* a = new assignment;
8fc05e57
DS
2000 a->tok = e->tok;
2001 a->op = "=";
a7999c82
JS
2002 a->left = tidsym;
2003 a->right = fc;
8fc05e57 2004
a7999c82 2005 expr_statement* es = new expr_statement;
8fc05e57
DS
2006 es->tok = e->tok;
2007 es->value = a;
ba6f838d 2008 add_probe->body = new block(add_probe->body, es);
85ecf79a 2009
a7999c82
JS
2010 vardecl* vd = new vardecl;
2011 vd->tok = e->tok;
2012 vd->name = tidsym->name;
2013 vd->type = pe_long;
2014 vd->set_arity(0);
2015 add_probe->locals.push_back(vd);
85ecf79a 2016 }
cf2a1f85 2017
a7999c82
JS
2018 // Save the value, like this:
2019 // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
2020 // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
2021 // = ${param}
2022 arrayindex* ai_tvar_preinc = new arrayindex;
2023 *ai_tvar_preinc = *ai_tvar_base;
2024
2025 pre_crement* preinc = new pre_crement;
2026 preinc->tok = e->tok;
2027 preinc->op = "++";
2028 preinc->operand = ai_ctr;
2029 ai_tvar_preinc->indexes.push_back(preinc);
2030
2031 a = new assignment;
2032 a->tok = e->tok;
2033 a->op = "=";
2034 a->left = ai_tvar_preinc;
2035 a->right = e;
2036
2037 es = new expr_statement;
2038 es->tok = e->tok;
2039 es->value = a;
2040
2041 add_probe->body = new block(add_probe->body, es);
2042
2043 // (4) Provide the '_dwarf_tvar_{name}_{num}_tmp' variable to
2044 // our parent so it can be used as a substitute for the target
2045 // symbol.
2046 provide (tmpsym);
2047
2048 // (5) Remember this replacement since we might be able to reuse
2049 // it later if the same return probe references this target
2050 // symbol again.
2051 return_ts_map[ts_name] = tmpsym;
2052}
41c262f3 2053
03c75a4a 2054
a7999c82
JS
2055void
2056dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
2057{
2058 Dwarf_Die *scopes;
2059 if (dwarf_getscopes_die (scope_die, &scopes) == 0)
2060 return;
0a98fd42 2061 auto_free free_scopes(scopes);
2cb3fe26 2062
a7999c82
JS
2063 target_symbol *tsym = new target_symbol;
2064 print_format* pf = new print_format;
a43ba433 2065
a7999c82
JS
2066 // Convert $$parms to sprintf of a list of parms and active local vars
2067 // which we recursively evaluate
a43ba433 2068
a7999c82
JS
2069 // NB: we synthesize a new token here rather than reusing
2070 // e->tok, because print_format::print likes to use
2071 // its tok->content.
2072 token* pf_tok = new token;
2073 pf_tok->location = e->tok->location;
2074 pf_tok->type = tok_identifier;
2075 pf_tok->content = "sprint";
2cb3fe26 2076
a7999c82
JS
2077 pf->tok = pf_tok;
2078 pf->print_to_stream = false;
2079 pf->print_with_format = true;
2080 pf->print_with_delim = false;
2081 pf->print_with_newline = false;
2082 pf->print_char = false;
2083
2084 if (q.has_return && (e->base_name == "$$return"))
2085 {
2086 tsym->tok = e->tok;
2087 tsym->base_name = "$return";
2088
2089 // Ignore any variable that isn't accessible.
2090 tsym->saved_conversion_error = 0;
2091 expression *texp = tsym;
2092 texp = require (texp); // NB: throws nothing ...
2093 if (tsym->saved_conversion_error) // ... but this is how we know it happened.
a43ba433 2094 {
2cb3fe26 2095
a43ba433
FCE
2096 }
2097 else
2098 {
a7999c82
JS
2099 pf->raw_components += "return";
2100 pf->raw_components += "=%#x ";
2101 pf->args.push_back(texp);
2102 }
2103 }
2104 else
2105 {
2106 // non-.return probe: support $$parms, $$vars, $$locals
2107 Dwarf_Die result;
2108 if (dwarf_child (&scopes[0], &result) == 0)
2109 do
2110 {
2111 switch (dwarf_tag (&result))
00cf3709 2112 {
a7999c82
JS
2113 case DW_TAG_variable:
2114 if (e->base_name == "$$parms")
2115 continue;
2116 break;
2117 case DW_TAG_formal_parameter:
2118 if (e->base_name == "$$locals")
2119 continue;
2120 break;
2121
2122 default:
2123 continue;
2124 }
41c262f3 2125
a7999c82
JS
2126 const char *diename = dwarf_diename (&result);
2127 if (! diename) continue;
f76427a2 2128
a7999c82
JS
2129 tsym->tok = e->tok;
2130 tsym->base_name = "$";
2131 tsym->base_name += diename;
41c262f3 2132
a7999c82
JS
2133 // Ignore any variable that isn't accessible.
2134 tsym->saved_conversion_error = 0;
2135 expression *texp = tsym;
2136 texp = require (texp); // NB: throws nothing ...
2137 if (tsym->saved_conversion_error) // ... but this is how we know it happened.
2138 {
2139 if (q.sess.verbose>2)
a43ba433 2140 {
a7999c82
JS
2141 for (semantic_error *c = tsym->saved_conversion_error;
2142 c != 0;
2143 c = c->chain) {
2144 clog << "variable location problem: " << c->what() << endl;
2145 }
a43ba433 2146 }
a7999c82
JS
2147
2148 pf->raw_components += diename;
2149 pf->raw_components += "=? ";
00cf3709 2150 }
a7999c82
JS
2151 else
2152 {
2153 pf->raw_components += diename;
2154 pf->raw_components += "=%#x ";
2155 pf->args.push_back(texp);
2156 }
2157 }
2158 while (dwarf_siblingof (&result, &result) == 0);
2159 }
2160
2161 pf->components = print_format::string_to_components(pf->raw_components);
2162 provide (pf);
2163}
2164
2cb3fe26 2165
a7999c82
JS
2166void
2167dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e)
2168{
2169 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
2170 visited = true;
2171
2172 bool lvalue = is_active_lvalue(e);
2173 if (lvalue && !q.sess.guru_mode)
2174 throw semantic_error("write to target variable not permitted", e->tok);
2175
2176 // See if we need to generate a new probe to save/access function
2177 // parameters from a return probe. PR 1382.
2178 if (q.has_return
2179 && e->base_name != "$return" // not the special return-value variable handled below
2180 && e->base_name != "$$return") // nor the other special variable handled below
2181 {
2182 if (lvalue)
2183 throw semantic_error("write to target variable not permitted in .return probes", e->tok);
2184
2185 visit_target_symbol_saved_return(e);
2186 return;
2187 }
2188
2189 if (e->base_name == "$$vars"
2190 || e->base_name == "$$parms"
2191 || e->base_name == "$$locals"
2192 || (q.has_return && (e->base_name == "$$return")))
2193 {
2194 if (lvalue)
2195 throw semantic_error("cannot write to context variable", e->tok);
2196
2197 if (e->addressof)
2198 throw semantic_error("cannot take address of context variable", e->tok);
2cb3fe26 2199
a7999c82 2200 visit_target_symbol_context(e);
2cb3fe26
SC
2201 return;
2202 }
2203
e57b735a 2204 // Synthesize a function.
d7f3e0c5 2205 functiondecl *fdecl = new functiondecl;
7b99c7d3 2206 fdecl->tok = e->tok;
d7f3e0c5 2207 embeddedcode *ec = new embeddedcode;
5e309481 2208 ec->tok = e->tok;
e8fbc5e8 2209
1b07c728 2210 string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
20e4a32c 2211 + "_" + e->base_name.substr(1)
e57b735a
GH
2212 + "_" + lex_cast<string>(tick++));
2213
66d284f4 2214 try
e57b735a 2215 {
a43ba433 2216 if (q.has_return && (e->base_name == "$return"))
e19fda4e
DS
2217 {
2218 ec->code = q.dw.literal_stmt_for_return (scope_die,
2219 addr,
b4c34c26 2220 e,
e19fda4e
DS
2221 lvalue,
2222 fdecl->type);
2223 }
2224 else
2225 {
2226 ec->code = q.dw.literal_stmt_for_local (scope_die,
2227 addr,
2228 e->base_name.substr(1),
b4c34c26 2229 e,
e19fda4e
DS
2230 lvalue,
2231 fdecl->type);
2232 }
2233
1b07c728
FCE
2234 if (! lvalue)
2235 ec->code += "/* pure */";
66d284f4
FCE
2236 }
2237 catch (const semantic_error& er)
2238 {
3bd0d4df
RA
2239 if (!q.sess.skip_badvars)
2240 {
2241 // We suppress this error message, and pass the unresolved
2242 // target_symbol to the next pass. We hope that this value ends
2243 // up not being referenced after all, so it can be optimized out
2244 // quietly.
2245 provide (e);
2246 semantic_error* saveme = new semantic_error (er); // copy it
3bd0d4df
RA
2247 // NB: we can have multiple errors, since a $target variable
2248 // may be expanded in several different contexts:
2249 // function ("*") { $var }
2250 saveme->chain = e->saved_conversion_error;
2251 e->saved_conversion_error = saveme;
2252 }
ad002306 2253 else
3bd0d4df 2254 {
ad002306 2255 // Upon user request for ignoring context, the symbol is replaced
3bd0d4df
RA
2256 // with a literal 0 and a warning message displayed
2257 literal_number* ln_zero = new literal_number (0);
2258 ln_zero->tok = e->tok;
2259 provide (ln_zero);
8c1b9e27
FCE
2260 if (!q.sess.suppress_warnings)
2261 q.sess.print_warning ("Bad $context variable being substituted with literal 0",
2262 e->tok);
3bd0d4df 2263 }
1cde5ba5
JS
2264 delete fdecl;
2265 delete ec;
cbfbbf69 2266 return;
66d284f4 2267 }
e57b735a 2268
d7f3e0c5
GH
2269 fdecl->name = fname;
2270 fdecl->body = ec;
e57b735a
GH
2271 if (lvalue)
2272 {
2273 // Modify the fdecl so it carries a single pe_long formal
2274 // argument called "value".
2275
2276 // FIXME: For the time being we only support setting target
2277 // variables which have base types; these are 'pe_long' in
2278 // stap's type vocabulary. Strings and pointers might be
2279 // reasonable, some day, but not today.
2280
2281 vardecl *v = new vardecl;
2282 v->type = pe_long;
2283 v->name = "value";
2284 v->tok = e->tok;
2285 fdecl->formal_args.push_back(v);
2286 }
f76427a2 2287 q.sess.functions[fdecl->name]=fdecl;
d9b516ca 2288
e57b735a 2289 // Synthesize a functioncall.
d7f3e0c5
GH
2290 functioncall* n = new functioncall;
2291 n->tok = e->tok;
2292 n->function = fname;
35d4ab18 2293 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
e57b735a
GH
2294
2295 if (lvalue)
2296 {
2297 // Provide the functioncall to our parent, so that it can be
2298 // used to substitute for the assignment node immediately above
2299 // us.
2300 assert(!target_symbol_setter_functioncalls.empty());
2301 *(target_symbol_setter_functioncalls.top()) = n;
2302 }
2303
4ed05b15 2304 provide (n);
77de5e9e
GH
2305}
2306
2307
c24447be
JS
2308void
2309dwarf_var_expanding_visitor::visit_cast_op (cast_op *e)
2310{
2311 // Fill in our current module context if needed
2312 if (e->module.empty())
2313 e->module = q.dw.module_name;
2314
2315 var_expanding_visitor::visit_cast_op(e);
2316}
2317
2318
c4ce66a1
JS
2319struct dwarf_cast_query : public base_query
2320{
946e1a48 2321 cast_op& e;
c4ce66a1 2322 const bool lvalue;
c4ce66a1 2323
abb41d92
JS
2324 exp_type& pe_type;
2325 string& code;
c4ce66a1 2326
946e1a48 2327 dwarf_cast_query(dwflpp& dw, const string& module, cast_op& e,
abb41d92
JS
2328 bool lvalue, exp_type& pe_type, string& code):
2329 base_query(dw, module), e(e), lvalue(lvalue),
2330 pe_type(pe_type), code(code) {}
c4ce66a1
JS
2331
2332 void handle_query_module();
2333 int handle_query_cu(Dwarf_Die * cudie);
2334
2335 static int cast_query_cu (Dwarf_Die * cudie, void * arg);
2336};
2337
2338
c4ce66a1
JS
2339void
2340dwarf_cast_query::handle_query_module()
2341{
abb41d92 2342 if (!code.empty())
c4ce66a1
JS
2343 return;
2344
2345 // look for the type in each CU
2346 dw.iterate_over_cus(cast_query_cu, this);
2347}
2348
2349
2350int
2351dwarf_cast_query::handle_query_cu(Dwarf_Die * cudie)
2352{
abb41d92 2353 if (!code.empty())
c4ce66a1
JS
2354 return DWARF_CB_ABORT;
2355
2356 dw.focus_on_cu (cudie);
2357 Dwarf_Die* type_die = dw.declaration_resolve(e.type.c_str());
2358 if (type_die)
2359 {
2360 try
2361 {
b4c34c26 2362 code = dw.literal_stmt_for_pointer (type_die, &e,
c4ce66a1
JS
2363 lvalue, pe_type);
2364 }
946e1a48 2365 catch (const semantic_error& er)
c4ce66a1 2366 {
946e1a48
JS
2367 // XXX might be better to try again in another CU
2368 // NB: we can have multiple errors, since a @cast
2369 // may be expanded in several different contexts:
2370 // function ("*") { @cast(...) }
2371 semantic_error* new_er = new semantic_error(er);
2372 new_er->chain = e.saved_conversion_error;
2373 e.saved_conversion_error = new_er;
c4ce66a1 2374 }
c4ce66a1
JS
2375 return DWARF_CB_ABORT;
2376 }
2377 return DWARF_CB_OK;
2378}
2379
2380
2381int
2382dwarf_cast_query::cast_query_cu (Dwarf_Die * cudie, void * arg)
2383{
2384 dwarf_cast_query * q = static_cast<dwarf_cast_query *>(arg);
2385 if (pending_interrupts) return DWARF_CB_ABORT;
2386 return q->handle_query_cu(cudie);
2387}
2388
2389
2390struct dwarf_cast_expanding_visitor: public var_expanding_visitor
2391{
2392 systemtap_session& s;
2393 dwarf_builder& db;
2394
2395 dwarf_cast_expanding_visitor(systemtap_session& s, dwarf_builder& db):
2396 s(s), db(db) {}
2397 void visit_cast_op (cast_op* e);
fb0274bc 2398 void filter_special_modules(string& module);
c4ce66a1
JS
2399};
2400
2401
fb0274bc
JS
2402void dwarf_cast_expanding_visitor::filter_special_modules(string& module)
2403{
d90053e7 2404 // look for "<path/to/header>" or "kernel<path/to/header>"
fb0274bc 2405 // for those cases, build a module including that header
d90053e7
JS
2406 if (module[module.size() - 1] == '>' &&
2407 (module[0] == '<' || module.compare(0, 7, "kernel<") == 0))
fb0274bc
JS
2408 {
2409 string cached_module;
2410 if (s.use_cache)
2411 {
2412 // see if the cached module exists
a2639cb7 2413 cached_module = find_typequery_hash(s, module);
fb0274bc
JS
2414 if (!cached_module.empty())
2415 {
2416 int fd = open(cached_module.c_str(), O_RDONLY);
2417 if (fd != -1)
2418 {
2419 if (s.verbose > 2)
2420 clog << "Pass 2: using cached " << cached_module << endl;
2421 module = cached_module;
2422 close(fd);
2423 return;
2424 }
2425 }
2426 }
2427
2428 // no cached module, time to make it
d90053e7 2429 if (make_typequery(s, module) == 0)
fb0274bc 2430 {
fb0274bc
JS
2431 if (s.use_cache)
2432 {
2433 // try to save typequery in the cache
2434 if (s.verbose > 2)
d90053e7 2435 clog << "Copying " << module
fb0274bc 2436 << " to " << cached_module << endl;
d90053e7 2437 if (copy_file(module.c_str(),
fb0274bc 2438 cached_module.c_str()) != 0)
d90053e7 2439 cerr << "Copy failed (\"" << module << "\" to \""
fb0274bc
JS
2440 << cached_module << "\"): " << strerror(errno) << endl;
2441 }
2442 }
2443 }
2444}
2445
2446
c4ce66a1
JS
2447void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
2448{
2449 bool lvalue = is_active_lvalue(e);
2450 if (lvalue && !s.guru_mode)
2451 throw semantic_error("write to typecast value not permitted", e->tok);
2452
2453 if (e->module.empty())
2454 e->module = "kernel"; // "*" may also be reasonable to search all kernel modules
2455
c4ce66a1
JS
2456 string code;
2457 exp_type type = pe_long;
8b31197b
JS
2458
2459 // split the module string by ':' for alternatives
2460 vector<string> modules;
2461 tokenize(e->module, modules, ":");
2462 for (unsigned i = 0; code.empty() && i < modules.size(); ++i)
c4ce66a1 2463 {
8b31197b 2464 string& module = modules[i];
fb0274bc 2465 filter_special_modules(module);
abb41d92 2466
c4ce66a1
JS
2467 // NB: This uses '/' to distinguish between kernel modules and userspace,
2468 // which means that userspace modules won't get any PATH searching.
2469 dwflpp* dw;
707bf35e
JS
2470 try
2471 {
2472 if (module.find('/') == string::npos)
2473 {
2474 // kernel or kernel module target
ae2552da 2475 dw = db.get_kern_dw(s, module);
707bf35e
JS
2476 }
2477 else
2478 {
2479 module = find_executable (module); // canonicalize it
2480 dw = db.get_user_dw(s, module);
2481 }
2482 }
2483 catch (const semantic_error& er)
2484 {
2485 /* ignore and go to the next module */
2486 continue;
2487 }
c4ce66a1 2488
abb41d92 2489 dwarf_cast_query q (*dw, module, *e, lvalue, type, code);
51178501 2490 dw->iterate_over_modules(&query_module, &q);
c4ce66a1 2491 }
abb41d92
JS
2492
2493 if (code.empty())
c4ce66a1 2494 {
946e1a48
JS
2495 // We pass the unresolved cast_op to the next pass, and hope
2496 // that this value ends up not being referenced after all, so
2497 // it can be optimized out quietly.
c4ce66a1
JS
2498 provide (e);
2499 return;
2500 }
2501
2502 string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
2503 + "_" + e->base_name.substr(1)
2504 + "_" + lex_cast<string>(tick++));
2505
2506 // Synthesize a function.
2507 functiondecl *fdecl = new functiondecl;
2508 fdecl->tok = e->tok;
2509 fdecl->type = type;
2510 fdecl->name = fname;
2511
2512 embeddedcode *ec = new embeddedcode;
2513 ec->tok = e->tok;
2514 ec->code = code;
2515 fdecl->body = ec;
2516
2517 // Give the fdecl an argument for the pointer we're trying to cast
2518 vardecl *v1 = new vardecl;
2519 v1->type = pe_long;
2520 v1->name = "pointer";
2521 v1->tok = e->tok;
2522 fdecl->formal_args.push_back(v1);
2523
2524 if (lvalue)
2525 {
2526 // Modify the fdecl so it carries a second pe_long formal
2527 // argument called "value".
2528
2529 // FIXME: For the time being we only support setting target
2530 // variables which have base types; these are 'pe_long' in
2531 // stap's type vocabulary. Strings and pointers might be
2532 // reasonable, some day, but not today.
2533
2534 vardecl *v2 = new vardecl;
2535 v2->type = pe_long;
2536 v2->name = "value";
2537 v2->tok = e->tok;
2538 fdecl->formal_args.push_back(v2);
2539 }
2540 else
2541 ec->code += "/* pure */";
2542
2543 s.functions[fdecl->name] = fdecl;
2544
2545 // Synthesize a functioncall.
2546 functioncall* n = new functioncall;
2547 n->tok = e->tok;
2548 n->function = fname;
2549 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
2550 n->args.push_back(e->operand);
2551
2552 if (lvalue)
2553 {
2554 // Provide the functioncall to our parent, so that it can be
2555 // used to substitute for the assignment node immediately above
2556 // us.
2557 assert(!target_symbol_setter_functioncalls.empty());
2558 *(target_symbol_setter_functioncalls.top()) = n;
2559 }
2560
2561 provide (n);
77de5e9e
GH
2562}
2563
2564
b8da0ad1
FCE
2565void
2566dwarf_derived_probe::printsig (ostream& o) const
2567{
2568 // Instead of just printing the plain locations, we add a PC value
2569 // as a comment as a way of telling e.g. apart multiple inlined
2570 // function instances. This is distinct from the verbose/clog
2571 // output, since this part goes into the cache hash calculations.
2572 sole_location()->print (o);
6d0f3f0c 2573 o << " /* pc=" << section << "+0x" << hex << addr << dec << " */";
b8da0ad1
FCE
2574 printsig_nested (o);
2575}
2576
2577
2578
dc38c0ae 2579void
b20febf3
FCE
2580dwarf_derived_probe::join_group (systemtap_session& s)
2581{
2582 if (! s.dwarf_derived_probes)
2583 s.dwarf_derived_probes = new dwarf_derived_probe_group ();
2584 s.dwarf_derived_probes->enroll (this);
2585}
2586
2587
2588dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
2589 const string& filename,
2590 int line,
91af0778 2591 // module & section specify a relocation
b20febf3
FCE
2592 // base for <addr>, unless section==""
2593 // (equivalently module=="kernel")
2594 const string& module,
2595 const string& section,
2596 // NB: dwfl_addr is the virtualized
2597 // address for this symbol.
2598 Dwarf_Addr dwfl_addr,
2599 // addr is the section-offset for
2600 // actual relocation.
2601 Dwarf_Addr addr,
2602 dwarf_query& q,
37ebca01 2603 Dwarf_Die* scope_die /* may be null */)
1939ea32 2604 : derived_probe (q.base_probe, new probe_point(*q.base_loc) /* .components soon rewritten */ ),
b20febf3 2605 module (module), section (section), addr (addr),
c9bad430
DS
2606 has_return (q.has_return),
2607 has_maxactive (q.has_maxactive),
2608 maxactive_val (q.maxactive_val)
bd2b1e68 2609{
b20febf3 2610 // Assert relocation invariants
4baf0e53 2611 if (section == "" && dwfl_addr != addr) // addr should be absolute
84048984
FCE
2612 throw semantic_error ("missing relocation base against", q.base_loc->tok);
2613 if (section != "" && dwfl_addr == addr) // addr should be an offset
b20febf3 2614 throw semantic_error ("inconsistent relocation address", q.base_loc->tok);
df8fadee 2615
b20febf3 2616 this->tok = q.base_probe->tok;
b95e2b79 2617 this->access_vars = false;
2930abc7 2618
21beacc9
FCE
2619 // XXX: hack for strange g++/gcc's
2620#ifndef USHRT_MAX
2621#define USHRT_MAX 32767
2622#endif
2623
606fd9c8
FCE
2624 // Range limit maxactive() value
2625 if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX))
2626 throw semantic_error ("maxactive value out of range [0,"
2627 + lex_cast<string>(USHRT_MAX) + "]",
2628 q.base_loc->tok);
2629
de688825 2630 // Expand target variables in the probe body
5f0a03a6 2631 if (!null_die(scope_die))
8fc05e57 2632 {
de688825 2633 dwarf_var_expanding_visitor v (q, scope_die, dwfl_addr);
4ed05b15 2634 this->body = v.require (this->body);
b95e2b79 2635 this->access_vars = v.visited;
37ebca01
FCE
2636
2637 // If during target-variable-expanding the probe, we added a new block
2638 // of code, add it to the start of the probe.
2639 if (v.add_block)
ba6f838d 2640 this->body = new block(v.add_block, this->body);
37ebca01
FCE
2641 // If when target-variable-expanding the probe, we added a new
2642 // probe, add it in a new file to the list of files to be processed.
2643 if (v.add_probe)
2644 {
2645 stapfile *f = new stapfile;
2646 f->probes.push_back(v.add_probe);
2647 q.sess.files.push_back(f);
2648 }
8fc05e57 2649 }
37ebca01 2650 // else - null scope_die - $target variables will produce an error during translate phase
8fc05e57 2651
0a98fd42
JS
2652 // Save the local variables for listing mode
2653 if (q.sess.listing_mode_vars)
2654 saveargs(scope_die);
2655
5d23847d 2656 // Reset the sole element of the "locations" vector as a
b20febf3
FCE
2657 // "reverse-engineered" form of the incoming (q.base_loc) probe
2658 // point. This allows a user to see what function / file / line
2659 // number any particular match of the wildcards.
2930abc7 2660
a229fcd7 2661 vector<probe_point::component*> comps;
91af0778
FCE
2662 if (q.has_kernel)
2663 comps.push_back (new probe_point::component(TOK_KERNEL));
2664 else if(q.has_module)
2665 comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module)));
2666 else if(q.has_process)
2667 comps.push_back (new probe_point::component(TOK_PROCESS, new literal_string(module)));
2668 else
2669 assert (0);
b5d77020 2670
db520b00
FCE
2671 string fn_or_stmt;
2672 if (q.has_function_str || q.has_function_num)
2673 fn_or_stmt = "function";
2674 else
2675 fn_or_stmt = "statement";
a229fcd7 2676
b8da0ad1 2677 if (q.has_function_str || q.has_statement_str)
db520b00 2678 {
4cd232e4 2679 string retro_name = funcname;
b20febf3 2680 if (filename != "")
cee35f73 2681 {
fb84c077 2682 retro_name += ("@" + string (filename));
cee35f73 2683 if (line > 0)
fb84c077 2684 retro_name += (":" + lex_cast<string> (line));
cee35f73 2685 }
db520b00
FCE
2686 comps.push_back
2687 (new probe_point::component
2688 (fn_or_stmt, new literal_string (retro_name)));
2689 }
b8da0ad1 2690 else if (q.has_function_num || q.has_statement_num)
db520b00
FCE
2691 {
2692 Dwarf_Addr retro_addr;
2693 if (q.has_function_num)
2694 retro_addr = q.function_num_val;
2695 else
2696 retro_addr = q.statement_num_val;
db520b00
FCE
2697 comps.push_back (new probe_point::component
2698 (fn_or_stmt,
2699 new literal_number(retro_addr))); // XXX: should be hex if possible
37ebca01
FCE
2700
2701 if (q.has_absolute)
2702 comps.push_back (new probe_point::component (TOK_ABSOLUTE));
a229fcd7
GH
2703 }
2704
b8da0ad1
FCE
2705 if (q.has_call)
2706 comps.push_back (new probe_point::component(TOK_CALL));
2707 if (q.has_inline)
2708 comps.push_back (new probe_point::component(TOK_INLINE));
db520b00 2709 if (has_return)
b8da0ad1
FCE
2710 comps.push_back (new probe_point::component(TOK_RETURN));
2711 if (has_maxactive)
2712 comps.push_back (new probe_point::component
2713 (TOK_MAXACTIVE, new literal_number(maxactive_val)));
d9b516ca 2714
5d23847d
FCE
2715 // Overwrite it.
2716 this->sole_location()->components = comps;
2930abc7
FCE
2717}
2718
bd2b1e68 2719
0a98fd42
JS
2720static bool dwarf_type_name(Dwarf_Die& type_die, string& c_type);
2721
2722void
2723dwarf_derived_probe::saveargs(Dwarf_Die* scope_die)
2724{
2725 Dwarf_Die *scopes;
2726 if (!null_die(scope_die) && dwarf_getscopes_die (scope_die, &scopes) == 0)
2727 return;
2728 auto_free free_scopes(scopes);
2729
2730 stringstream argstream;
2731 string type_name;
2732 Dwarf_Attribute type_attr;
2733 Dwarf_Die type_die;
2734
2735 if (has_return &&
2736 dwarf_attr_integrate (scope_die, DW_AT_type, &type_attr) &&
2737 dwarf_formref_die (&type_attr, &type_die) &&
2738 dwarf_type_name(type_die, type_name))
2739 argstream << " $return:" << type_name;
2740
2741 Dwarf_Die arg;
2742 if (dwarf_child (&scopes[0], &arg) == 0)
2743 do
2744 {
2745 switch (dwarf_tag (&arg))
2746 {
2747 case DW_TAG_variable:
2748 case DW_TAG_formal_parameter:
2749 break;
2750
2751 default:
2752 continue;
2753 }
2754
2755 const char *arg_name = dwarf_diename (&arg);
2756 if (!arg_name)
2757 continue;
2758
2759 type_name.clear();
2760 if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) ||
2761 !dwarf_formref_die (&type_attr, &type_die) ||
2762 !dwarf_type_name(type_die, type_name))
2763 continue;
2764
2765 argstream << " $" << arg_name << ":" << type_name;
2766 }
2767 while (dwarf_siblingof (&arg, &arg) == 0);
2768
2769 args = argstream.str();
2770}
2771
2772
2773void
2774dwarf_derived_probe::printargs(std::ostream &o) const
2775{
2776 o << args;
2777}
2778
2779
7a053d3b 2780void
20c6c071 2781dwarf_derived_probe::register_statement_variants(match_node * root,
bd2b1e68
GH
2782 dwarf_builder * dw)
2783{
54efe513 2784 root->bind(dw);
54efe513
GH
2785}
2786
7a053d3b 2787void
fd6602a0 2788dwarf_derived_probe::register_function_variants(match_node * root,
c9bad430 2789 dwarf_builder * dw)
bd2b1e68 2790{
fd6602a0 2791 root->bind(dw);
b8da0ad1
FCE
2792 root->bind(TOK_INLINE)->bind(dw);
2793 root->bind(TOK_CALL)->bind(dw);
fd6602a0 2794 root->bind(TOK_RETURN)->bind(dw);
c9bad430 2795 root->bind(TOK_RETURN)->bind_num(TOK_MAXACTIVE)->bind(dw);
bd2b1e68
GH
2796}
2797
7a053d3b 2798void
20c6c071 2799dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
bd2b1e68
GH
2800 dwarf_builder * dw)
2801{
2802 // Here we match 4 forms:
2803 //
2804 // .function("foo")
2805 // .function(0xdeadbeef)
2806 // .statement("foo")
2807 // .statement(0xdeadbeef)
2808
fd6602a0
FCE
2809 register_function_variants(root->bind_str(TOK_FUNCTION), dw);
2810 register_function_variants(root->bind_num(TOK_FUNCTION), dw);
20c6c071
GH
2811 register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
2812 register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
bd2b1e68
GH
2813}
2814
2815void
c4ce66a1 2816dwarf_derived_probe::register_patterns(systemtap_session& s)
bd2b1e68 2817{
c4ce66a1 2818 match_node* root = s.pattern_root;
bd2b1e68
GH
2819 dwarf_builder *dw = new dwarf_builder();
2820
c4ce66a1
JS
2821 update_visitor *filter = new dwarf_cast_expanding_visitor(s, *dw);
2822 s.code_filters.push_back(filter);
2823
20c6c071
GH
2824 register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
2825 register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
37ebca01 2826 root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
0f336e95
SC
2827 root->bind(TOK_KERNEL)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
2828 root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
37ebca01 2829
7a24d422 2830 register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
f28a8c28
SC
2831 root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)->bind(dw);
2832 root->bind_str(TOK_PROCESS)->bind_num(TOK_MARK)->bind(dw);
bd2b1e68
GH
2833}
2834
9020300d
FCE
2835void
2836dwarf_derived_probe::emit_probe_local_init(translator_output * o)
2837{
b95e2b79
MH
2838 if (access_vars)
2839 {
2840 // if accessing $variables, emit bsp cache setup for speeding up
2841 o->newline() << "bspcache(c->unwaddr, c->regs);";
2842 }
9020300d 2843}
2930abc7 2844
b20febf3 2845// ------------------------------------------------------------------------
46b84a80
DS
2846
2847void
b20febf3 2848dwarf_derived_probe_group::enroll (dwarf_derived_probe* p)
46b84a80 2849{
b20febf3 2850 probes_by_module.insert (make_pair (p->module, p));
b8da0ad1
FCE
2851
2852 // XXX: probes put at the same address should all share a
2853 // single kprobe/kretprobe, and have their handlers executed
2854 // sequentially.
b55bc428
FCE
2855}
2856
7a053d3b 2857void
775d51e5 2858dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
ec4373ff 2859{
b20febf3 2860 if (probes_by_module.empty()) return;
2930abc7 2861
775d51e5
DS
2862 s.op->newline() << "/* ---- dwarf probes ---- */";
2863
2864 // Warn of misconfigured kernels
f41595cc
FCE
2865 s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
2866 s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
2867 s.op->newline() << "#endif";
775d51e5 2868 s.op->newline();
f41595cc 2869
f07c3b68
FCE
2870 s.op->newline() << "#ifndef KRETACTIVE";
2871 s.op->newline() << "#define KRETACTIVE (max(15,6*NR_CPUS))";
2872 s.op->newline() << "#endif";
2873
b20febf3
FCE
2874 // Forward declare the master entry functions
2875 s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
2876 s.op->line() << " struct pt_regs *regs);";
2877 s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
2878 s.op->line() << " struct pt_regs *regs);";
2879
42cb22bd
MH
2880 // Emit an array of kprobe/kretprobe pointers
2881 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
2882 s.op->newline() << "static void * stap_unreg_kprobes[" << probes_by_module.size() << "];";
2883 s.op->newline() << "#endif";
2884
b20febf3 2885 // Emit the actual probe list.
606fd9c8
FCE
2886
2887 // NB: we used to plop a union { struct kprobe; struct kretprobe } into
2888 // struct stap_dwarf_probe, but it being initialized data makes it add
2889 // hundreds of bytes of padding per stap_dwarf_probe. (PR5673)
4c2732a1 2890 s.op->newline() << "static struct stap_dwarf_kprobe {";
b20febf3 2891 s.op->newline(1) << "union { struct kprobe kp; struct kretprobe krp; } u;";
e4cb375f
MH
2892 s.op->newline() << "#ifdef __ia64__";
2893 s.op->newline() << "struct kprobe dummy;";
2894 s.op->newline() << "#endif";
606fd9c8
FCE
2895 s.op->newline(-1) << "} stap_dwarf_kprobes[" << probes_by_module.size() << "];";
2896 // NB: bss!
2897
4c2732a1 2898 s.op->newline() << "static struct stap_dwarf_probe {";
b0986e7a
DS
2899 s.op->newline(1) << "const unsigned return_p:1;";
2900 s.op->newline() << "const unsigned maxactive_p:1;";
b350f56b 2901 s.op->newline() << "const unsigned optional_p:1;";
b20febf3 2902 s.op->newline() << "unsigned registered_p:1;";
b0986e7a 2903 s.op->newline() << "const unsigned short maxactive_val;";
606fd9c8
FCE
2904
2905 // Let's find some stats for the three embedded strings. Maybe they
2906 // are small and uniform enough to justify putting char[MAX]'s into
2907 // the array instead of relocated char*'s.
2908 size_t module_name_max = 0, section_name_max = 0, pp_name_max = 0;
2909 size_t module_name_tot = 0, section_name_tot = 0, pp_name_tot = 0;
2910 size_t all_name_cnt = probes_by_module.size(); // for average
2911 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
2912 {
2913 dwarf_derived_probe* p = it->second;
2914#define DOIT(var,expr) do { \
2915 size_t var##_size = (expr) + 1; \
2916 var##_max = max (var##_max, var##_size); \
2917 var##_tot += var##_size; } while (0)
2918 DOIT(module_name, p->module.size());
2919 DOIT(section_name, p->section.size());
2920 DOIT(pp_name, lex_cast_qstring(*p->sole_location()).size());
2921#undef DOIT
2922 }
2923
2924 // Decide whether it's worthwhile to use char[] or char* by comparing
2925 // the amount of average waste (max - avg) to the relocation data size
2926 // (3 native long words).
2927#define CALCIT(var) \
2928 if ((var##_name_max-(var##_name_tot/all_name_cnt)) < (3 * sizeof(void*))) \
2929 { \
2930 s.op->newline() << "const char " << #var << "[" << var##_name_max << "];"; \
2931 if (s.verbose > 2) clog << "stap_dwarf_probe " << #var \
2932 << "[" << var##_name_max << "]" << endl; \
2933 } \
2934 else \
2935 { \
b0986e7a 2936 s.op->newline() << "const char * const " << #var << ";"; \
606fd9c8
FCE
2937 if (s.verbose > 2) clog << "stap_dwarf_probe *" << #var << endl; \
2938 }
2939
2940 CALCIT(module);
2941 CALCIT(section);
2942 CALCIT(pp);
e6fe60e7 2943#undef CALCIT
606fd9c8 2944
b0986e7a
DS
2945 s.op->newline() << "const unsigned long address;";
2946 s.op->newline() << "void (* const ph) (struct context*);";
b20febf3
FCE
2947 s.op->newline(-1) << "} stap_dwarf_probes[] = {";
2948 s.op->indent(1);
2949
2950 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
2930abc7 2951 {
b20febf3
FCE
2952 dwarf_derived_probe* p = it->second;
2953 s.op->newline() << "{";
2954 if (p->has_return)
2955 s.op->line() << " .return_p=1,";
c9bad430 2956 if (p->has_maxactive)
606fd9c8
FCE
2957 {
2958 s.op->line() << " .maxactive_p=1,";
2959 assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
2960 s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
2961 }
b350f56b
JS
2962 if (p->locations[0]->optional)
2963 s.op->line() << " .optional_p=1,";
dc38c256 2964 s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
84048984
FCE
2965 s.op->line() << " .module=\"" << p->module << "\",";
2966 s.op->line() << " .section=\"" << p->section << "\",";
b20febf3
FCE
2967 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
2968 s.op->line() << " .ph=&" << p->name;
2969 s.op->line() << " },";
2930abc7 2970 }
2930abc7 2971
b20febf3
FCE
2972 s.op->newline(-1) << "};";
2973
2974 // Emit the kprobes callback function
2975 s.op->newline();
2976 s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
2977 s.op->line() << " struct pt_regs *regs) {";
606fd9c8
FCE
2978 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
2979 s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
2980 // Check that the index is plausible
2981 s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
2982 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
2983 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
2984 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
2985 s.op->line() << "];";
c12d974f 2986 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp");
b20febf3 2987 s.op->newline() << "c->regs = regs;";
6415ddde
MW
2988
2989 // Make it look like the IP is set as it wouldn't have been replaced
2990 // by a breakpoint instruction when calling real probe handler. Reset
2991 // IP regs on return, so we don't confuse kprobes. PR10458
2992 s.op->newline() << "{";
2993 s.op->indent(1);
2994 s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
2995 s.op->newline() << "REG_IP(regs) = (unsigned long) inst->addr;";
b20febf3 2996 s.op->newline() << "(*sdp->ph) (c);";
6415ddde
MW
2997 s.op->newline() << "REG_IP(regs) = kprobes_ip;";
2998 s.op->newline(-1) << "}";
2999
b20febf3
FCE
3000 common_probe_entryfn_epilogue (s.op);
3001 s.op->newline() << "return 0;";
3002 s.op->newline(-1) << "}";
3003
3004 // Same for kretprobes
3005 s.op->newline();
3006 s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
3007 s.op->line() << " struct pt_regs *regs) {";
3008 s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
606fd9c8
FCE
3009
3010 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
a36378d7 3011 s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
606fd9c8
FCE
3012 // Check that the index is plausible
3013 s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
3014 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
3015 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
3016 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
3017 s.op->line() << "];";
3018
c12d974f 3019 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp");
b20febf3
FCE
3020 s.op->newline() << "c->regs = regs;";
3021 s.op->newline() << "c->pi = inst;"; // for assisting runtime's backtrace logic
6415ddde
MW
3022
3023 // Make it look like the IP is set as it wouldn't have been replaced
3024 // by a breakpoint instruction when calling real probe handler. Reset
3025 // IP regs on return, so we don't confuse kprobes. PR10458
3026 s.op->newline() << "{";
3027 s.op->indent(1);
3028 s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
3029 s.op->newline() << "REG_IP(regs) = (unsigned long) inst->rp->kp.addr;";
b20febf3 3030 s.op->newline() << "(*sdp->ph) (c);";
6415ddde
MW
3031 s.op->newline() << "REG_IP(regs) = kprobes_ip;";
3032 s.op->newline(-1) << "}";
3033
b20febf3
FCE
3034 common_probe_entryfn_epilogue (s.op);
3035 s.op->newline() << "return 0;";
3036 s.op->newline(-1) << "}";
20c6c071 3037}
ec4373ff 3038
20c6c071 3039
dc38c0ae 3040void
b20febf3
FCE
3041dwarf_derived_probe_group::emit_module_init (systemtap_session& s)
3042{
3043 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
3044 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
a36378d7 3045 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
f1bad60c 3046 s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address);";
b20febf3 3047 s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent
6d0f3f0c 3048 s.op->newline() << "probe_point = sdp->pp;"; // for error messages
b20febf3 3049 s.op->newline() << "if (sdp->return_p) {";
606fd9c8 3050 s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;";
c9bad430 3051 s.op->newline() << "if (sdp->maxactive_p) {";
606fd9c8 3052 s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
c9bad430 3053 s.op->newline(-1) << "} else {";
f07c3b68 3054 s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;";
c9bad430 3055 s.op->newline(-1) << "}";
606fd9c8 3056 s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
e4cb375f
MH
3057 // to ensure safeness of bspcache, always use aggr_kprobe on ia64
3058 s.op->newline() << "#ifdef __ia64__";
3059 s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;";
3060 s.op->newline() << "kp->dummy.pre_handler = NULL;";
3061 s.op->newline() << "rc = register_kprobe (& kp->dummy);";
3062 s.op->newline() << "if (rc == 0) {";
3063 s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);";
3064 s.op->newline() << "if (rc != 0)";
3065 s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
3066 s.op->newline(-2) << "}";
3067 s.op->newline() << "#else";
606fd9c8 3068 s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
e4cb375f 3069 s.op->newline() << "#endif";
b20febf3 3070 s.op->newline(-1) << "} else {";
e4cb375f 3071 // to ensure safeness of bspcache, always use aggr_kprobe on ia64
606fd9c8
FCE
3072 s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
3073 s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
e4cb375f
MH
3074 s.op->newline() << "#ifdef __ia64__";
3075 s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
3076 s.op->newline() << "kp->dummy.pre_handler = NULL;";
3077 s.op->newline() << "rc = register_kprobe (& kp->dummy);";
3078 s.op->newline() << "if (rc == 0) {";
3079 s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);";
3080 s.op->newline() << "if (rc != 0)";
3081 s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
3082 s.op->newline(-2) << "}";
3083 s.op->newline() << "#else";
606fd9c8 3084 s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
e4cb375f 3085 s.op->newline() << "#endif";
b20febf3 3086 s.op->newline(-1) << "}";
9063462a
FCE
3087 s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
3088 s.op->newline(1) << "sdp->registered_p = 0;";
b350f56b 3089 s.op->newline() << "if (!sdp->optional_p)";
4a4edc21 3090 s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, relocated_addr, rc);";
b350f56b 3091 s.op->newline(-1) << "rc = 0;"; // continue with other probes
9063462a
FCE
3092 // XXX: shall we increment numskipped?
3093 s.op->newline(-1) << "}";
3094
3095#if 0 /* pre PR 6749; XXX consider making an option */
c48cb0cc 3096 s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
b20febf3 3097 s.op->newline(1) << "struct stap_dwarf_probe *sdp2 = & stap_dwarf_probes[j];";
606fd9c8
FCE
3098 s.op->newline() << "struct stap_dwarf_kprobe *kp2 = & stap_dwarf_kprobes[j];";
3099 s.op->newline() << "if (sdp2->return_p) unregister_kretprobe (&kp2->u.krp);";
3100 s.op->newline() << "else unregister_kprobe (&kp2->u.kp);";
e4cb375f
MH
3101 s.op->newline() << "#ifdef __ia64__";
3102 s.op->newline() << "unregister_kprobe (&kp2->dummy);";
3103 s.op->newline() << "#endif";
c48cb0cc
FCE
3104 // NB: we don't have to clear sdp2->registered_p, since the module_exit code is
3105 // not run for this early-abort case.
3106 s.op->newline(-1) << "}";
3107 s.op->newline() << "break;"; // don't attempt to register any more probes
b20febf3 3108 s.op->newline(-1) << "}";
9063462a
FCE
3109#endif
3110
b20febf3
FCE
3111 s.op->newline() << "else sdp->registered_p = 1;";
3112 s.op->newline(-1) << "}"; // for loop
dc38c0ae
DS
3113}
3114
3115
46b84a80 3116void
b20febf3 3117dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
46b84a80 3118{
42cb22bd
MH
3119 //Unregister kprobes by batch interfaces.
3120 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
3121 s.op->newline() << "j = 0;";
3122 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
3123 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
3124 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
3125 s.op->newline() << "if (! sdp->registered_p) continue;";
3126 s.op->newline() << "if (!sdp->return_p)";
3127 s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.kp;";
3128 s.op->newline(-2) << "}";
3129 s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
3130 s.op->newline() << "j = 0;";
3131 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
3132 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
3133 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
3134 s.op->newline() << "if (! sdp->registered_p) continue;";
3135 s.op->newline() << "if (sdp->return_p)";
3136 s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.krp;";
3137 s.op->newline(-2) << "}";
3138 s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, j);";
e4cb375f
MH
3139 s.op->newline() << "#ifdef __ia64__";
3140 s.op->newline() << "j = 0;";
3141 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
3142 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
3143 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
3144 s.op->newline() << "if (! sdp->registered_p) continue;";
3145 s.op->newline() << "stap_unreg_kprobes[j++] = &kp->dummy;";
3146 s.op->newline(-1) << "}";
3147 s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
3148 s.op->newline() << "#endif";
42cb22bd
MH
3149 s.op->newline() << "#endif";
3150
b20febf3
FCE
3151 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
3152 s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
a36378d7 3153 s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
b20febf3
FCE
3154 s.op->newline() << "if (! sdp->registered_p) continue;";
3155 s.op->newline() << "if (sdp->return_p) {";
42cb22bd 3156 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
606fd9c8 3157 s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
42cb22bd 3158 s.op->newline() << "#endif";
606fd9c8 3159 s.op->newline() << "atomic_add (kp->u.krp.nmissed, & skipped_count);";
73209876
FCE
3160 s.op->newline() << "#ifdef STP_TIMING";
3161 s.op->newline() << "if (kp->u.krp.nmissed)";
d01eaa30 3162 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->pp, kp->u.krp.nmissed);";
73209876 3163 s.op->newline(-1) << "#endif";
606fd9c8 3164 s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
73209876
FCE
3165 s.op->newline() << "#ifdef STP_TIMING";
3166 s.op->newline() << "if (kp->u.krp.kp.nmissed)";
d01eaa30 3167 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %d\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
73209876 3168 s.op->newline(-1) << "#endif";
557fb7a8 3169 s.op->newline(-1) << "} else {";
42cb22bd 3170 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
606fd9c8 3171 s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
42cb22bd 3172 s.op->newline() << "#endif";
606fd9c8 3173 s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
73209876
FCE
3174 s.op->newline() << "#ifdef STP_TIMING";
3175 s.op->newline() << "if (kp->u.kp.nmissed)";
d01eaa30 3176 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %d\\n\", sdp->pp, kp->u.kp.nmissed);";
73209876 3177 s.op->newline(-1) << "#endif";
b20febf3 3178 s.op->newline(-1) << "}";
e4cb375f
MH
3179 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
3180 s.op->newline() << "unregister_kprobe (&kp->dummy);";
3181 s.op->newline() << "#endif";
b20febf3
FCE
3182 s.op->newline() << "sdp->registered_p = 0;";
3183 s.op->newline(-1) << "}";
46b84a80
DS
3184}
3185
7a05f484
SC
3186struct sdt_var_expanding_visitor: public var_expanding_visitor
3187{
9f02b156 3188 sdt_var_expanding_visitor(string & process_name, string & probe_name,
0c3bfb1e 3189 int arg_count, bool have_reg_args, bool utrace_probe):
9f02b156 3190 process_name (process_name), probe_name (probe_name),
0c3bfb1e
SC
3191 have_reg_args (have_reg_args), utrace_probe (utrace_probe),
3192 arg_count (arg_count)
a8ec7719
JS
3193 {
3194 assert(!have_reg_args || (arg_count >= 0 && arg_count <= 10));
3195 }
56e33af5
SC
3196 string & process_name;
3197 string & probe_name;
7a05f484 3198 bool have_reg_args;
0c3bfb1e 3199 bool utrace_probe;
7a05f484
SC
3200 int arg_count;
3201
3202 void visit_target_symbol (target_symbol* e);
3203};
3204
3205void
3206sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
3207{
3208 if (e->base_name == "$$name")
3209 {
03c75a4a
JS
3210 if (e->addressof)
3211 throw semantic_error("cannot take address of sdt variable", e->tok);
3212
7a05f484
SC
3213 literal_string *myname = new literal_string (probe_name);
3214 myname->tok = e->tok;
3215 provide(myname);
3216 return;
3217 }
3218 else if (e->base_name.find("$arg") == string::npos || ! have_reg_args)
3219 {
3220 provide(e);
3221 return;
3222 }
a8ec7719
JS
3223
3224 int argno = lex_cast<int>(e->base_name.substr(4));
3225 if (argno < 1 || argno > arg_count)
3226 throw semantic_error ("invalid argument number", e->tok);
3227
7a05f484 3228 bool lvalue = is_active_lvalue(e);
7a05f484
SC
3229 functioncall *fc = new functioncall;
3230
5111fc3e
SC
3231 // First two args are hidden: 1. pointer to probe name 2. task id
3232 if (arg_count < 2)
7a05f484 3233 {
0c3bfb1e 3234 fc->function = utrace_probe ? "_utrace_syscall_arg" : "ulong_arg";
7a05f484
SC
3235 fc->type = pe_long;
3236 fc->tok = e->tok;
0c3bfb1e 3237 literal_number* num = new literal_number(argno + (utrace_probe ? 1 : 2));
7a05f484
SC
3238 num->tok = e->tok;
3239 fc->args.push_back(num);
3240 }
3241 else // args passed as a struct
3242 {
3243 fc->function = "user_long";
3244 fc->tok = e->tok;
3245 binary_expression *be = new binary_expression;
3246 be->tok = e->tok;
3247 functioncall *get_arg1 = new functioncall;
0c3bfb1e 3248 get_arg1->function = utrace_probe ? "_utrace_syscall_arg" : "pointer_arg";
7a05f484 3249 get_arg1->tok = e->tok;
0c3bfb1e 3250 literal_number* num = new literal_number((utrace_probe ? 2 : 3));
7a05f484
SC
3251 num->tok = e->tok;
3252 get_arg1->args.push_back(num);
3253
3254 be->left = get_arg1;
3255 be->op = "+";
3256 literal_number* inc = new literal_number((argno - 1) * 8);
3257 be->right = inc;
3258 fc->args.push_back(be);
3259 }
ad002306 3260
7a05f484
SC
3261 if (lvalue)
3262 *(target_symbol_setter_functioncalls.top()) = fc;
3263
ad002306
SC
3264 if (e->components.empty())
3265 {
03c75a4a
JS
3266 if (e->addressof)
3267 throw semantic_error("cannot take address of sdt variable", e->tok);
3268
ad002306
SC
3269 provide(fc);
3270 return;
3271 }
7a05f484
SC
3272 cast_op *cast = new cast_op;
3273 cast->base_name = "@cast";
3274 cast->tok = e->tok;
3275 cast->operand = fc;
3276 cast->components = e->components;
ad002306 3277 cast->type = probe_name + "_arg" + lex_cast<string>(argno);
56e33af5 3278 cast->module = process_name;
7a05f484 3279
ad002306 3280 provide(cast);
7a05f484 3281}
46b84a80 3282
edce5b67
JS
3283
3284struct sdt_query : public base_query
3285{
3286 sdt_query(probe * base_probe, probe_point * base_loc,
3287 dwflpp & dw, literal_map_t const & params,
3288 vector<derived_probe *> & results);
3289
3290 void handle_query_module();
3291
3292private:
3293 enum probe_types
3294 {
3295 uprobe_type = 0x31425250, // "PRB1"
3296 kprobe_type = 0x32425250, // "PRB2"
3297 utrace_type = 0x33425250, // "PRB3"
3298 } probe_type;
3299
3300 probe * base_probe;
3301 probe_point * base_loc;
3302 vector<derived_probe *> & results;
3303 string mark_name;
3304
3305 set<string> probes_handled;
3306
3307 Elf_Data *pdata;
3308 size_t probe_scn_offset;
3309 size_t probe_scn_addr;
3310 uint64_t probe_arg;
3311 string probe_name;
3312
3313 bool init_probe_scn();
3314 bool get_next_probe();
3315
3316 void convert_probe(probe *base);
3317 void convert_location(probe *base, probe_point *location);
3318};
3319
3320
3321sdt_query::sdt_query(probe * base_probe, probe_point * base_loc,
3322 dwflpp & dw, literal_map_t const & params,
3323 vector<derived_probe *> & results):
3324 base_query(dw, params), base_probe(base_probe),
3325 base_loc(base_loc), results(results)
3326{
3327 assert(get_string_param(params, TOK_MARK, mark_name));
3328}
3329
3330
3331void
3332sdt_query::handle_query_module()
3333{
3334 if (!init_probe_scn())
3335 return;
3336
3337 if (sess.verbose > 3)
3338 clog << "TOK_MARK: " << mark_name << endl;
3339
3340 while (get_next_probe())
3341 {
3342 if (!probes_handled.insert(probe_name).second)
3343 continue;
3344
3345 probe *new_base = new probe(*base_probe);
3346 probe_point *new_location = new probe_point(*base_loc);
3347 convert_location(new_base, new_location);
3348 new_base->body = deep_copy_visitor::deep_copy(base_probe->body);
3349
3350 bool have_reg_args = false;
3351 if (probe_type == kprobe_type || probe_type == utrace_type)
3352 {
3353 convert_probe(new_base);
3354 have_reg_args = true;
3355 }
3356
3357 // Expand the local variables in the probe body
3358 sdt_var_expanding_visitor svv (module_val, probe_name,
3359 probe_arg, have_reg_args,
3360 probe_type == utrace_type);
3361 new_base->body = svv.require (new_base->body);
3362
3363 unsigned i = results.size();
3364
3365 if (probe_type == kprobe_type || probe_type == utrace_type)
3366 derive_probes(sess, new_base, results);
3367 else
3368 {
3369 literal_map_t params;
3370 for (unsigned i = 0; i < new_location->components.size(); ++i)
3371 {
3372 probe_point::component *c = new_location->components[i];
3373 params[c->functor] = c->arg;
3374 }
3375
3376 dwarf_query q(base_probe, base_loc, dw, params, results);
3377 q.has_mark = true; // enables mid-statement probing
3378 dw.iterate_over_modules(&query_module, &q);
3379 }
3380
3381 if (sess.listing_mode)
3382 {
3383 // restore the locations to print a nicer probe name
3384 probe_point loc(*base_loc);
3385 loc.components[1] =
3386 new probe_point::component(TOK_MARK, new literal_string (probe_name));
3387 for (; i < results.size(); ++i)
3388 for (unsigned j = 0; j < results[i]->locations.size(); ++j)
3389 *results[i]->locations[j] = loc;
3390 }
3391 }
3392}
3393
3394
3395bool
3396sdt_query::init_probe_scn()
3397{
3398 Elf* elf;
3399 GElf_Shdr shdr_mem;
3400 GElf_Shdr *shdr = NULL;
3401 Dwarf_Addr bias;
3402 size_t shstrndx;
3403
3404 // Explicitly look in the main elf file first.
3405 elf = dwfl_module_getelf (dw.module, &bias);
3406 Elf_Scn *probe_scn = NULL;
3407
3408 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3409
3410 bool have_probes = false;
3411
3412 // Is there a .probes section?
3413 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3414 {
3415 shdr = gelf_getshdr (probe_scn, &shdr_mem);
3416 assert (shdr != NULL);
3417
3418 if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") == 0)
3419 {
3420 have_probes = true;
3421 break;
3422 }
3423 }
3424
3425 // Older versions put .probes section in the debuginfo dwarf file,
3426 // so check if it actually exists, if not take a look in the debuginfo file
3427 if (! have_probes || (have_probes && shdr->sh_type == SHT_NOBITS))
3428 {
3429 elf = dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias));
3430 if (! elf)
3431 return false;
3432 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3433 probe_scn = NULL;
3434 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3435 {
3436 shdr = gelf_getshdr (probe_scn, &shdr_mem);
3437 if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name),
3438 ".probes") == 0)
3439 have_probes = true;
3440 break;
3441 }
3442 }
3443
3444 if (!have_probes)
3445 return false;
3446
3447 pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE);
3448 probe_scn_offset = 0;
3449 probe_scn_addr = shdr->sh_addr;
3450 assert (pdata != NULL);
3451 if (sess.verbose > 4)
3452 clog << "got .probes elf scn_addr@0x" << probe_scn_addr << dec
3453 << ", size: " << pdata->d_size << endl;
3454 return true;
3455}
3456
3457bool
3458sdt_query::get_next_probe()
3459{
3460 // Extract probe info from the .probes section
3461
3462 while (probe_scn_offset < pdata->d_size)
3463 {
3464 struct probe_entry
3465 {
3466 __uint64_t name;
3467 __uint64_t arg;
3468 } *pbe;
3469 __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset);
3470 probe_type = (enum probe_types)*type;
3471 if (probe_type != uprobe_type && probe_type != kprobe_type
3472 && probe_type != utrace_type)
3473 {
3474 // Unless this is a mangled .probes section, this happens
3475 // because the name of the probe comes first, followed by
3476 // the sentinel.
3477 if (sess.verbose > 5)
3478 clog << "got unknown probe_type: 0x" << hex << probe_type
3479 << dec << endl;
3480 probe_scn_offset += sizeof(__uint32_t);
3481 continue;
3482 }
3483 probe_scn_offset += sizeof(__uint32_t);
3484 probe_scn_offset += probe_scn_offset % sizeof(__uint64_t);
3485 pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset);
3486 probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr);
3487 probe_arg = pbe->arg;
3488 if (sess.verbose > 4)
3489 clog << "saw .probes " << probe_name
3490 << "@0x" << hex << probe_arg << dec << endl;
3491
3492 probe_scn_offset += sizeof (struct probe_entry);
3493 if ((mark_name == probe_name)
3494 || (dw.name_has_wildcard (mark_name)
3495 && dw.function_name_matches_pattern (probe_name, mark_name)))
3496 {
3497 if (sess.verbose > 3)
3498 clog << "found probe_name" << probe_name << " at 0x"
3499 << hex << probe_arg << dec << endl;
3500 return true;
3501 }
3502 else
3503 continue;
3504 }
3505 return false;
3506}
3507
3508
3509void
3510sdt_query::convert_probe (probe *base)
3511{
3512 block *b = new block;
3513 b->tok = base->body->tok;
3514
3515 // XXX: Does this also need to happen for i386 under x86_64 stap?
3516#ifdef __i386__
3517 if (probe_type == kprobe_type)
3518 {
3519 functioncall *rp = new functioncall;
3520 rp->tok = b->tok;
3521 rp->function = "regparm";
3522 rp->tok = b->tok;
3523 literal_number* littid = new literal_number(0);
3524 littid->tok = b->tok;
3525 rp->args.push_back(littid);
3526 expr_statement* es = new expr_statement;
3527 es->tok = b->tok;
3528 es->value = rp;
3529 b->statements.push_back(es);
3530 }
3531#endif
3532
3533 if (probe_type == utrace_type)
3534 {
3535 // Generate: if ($syscall != 0xbead) next;
3536 if_statement *issc = new if_statement;
3537 issc->thenblock = new next_statement;
3538 issc->elseblock = NULL;
3539 issc->tok = b->tok;
3540 comparison *besc = new comparison;
3541 besc->op = "!=";
3542 besc->tok = b->tok;
3543 functioncall* n = new functioncall;
3544 n->tok = b->tok;
3545 n->function = "_utrace_syscall_nr";
3546 n->referent = 0;
3547 besc->left = n;
3548 literal_number* fake_syscall = new literal_number(0xbead);
3549 fake_syscall->tok = b->tok;
3550 besc->right = fake_syscall;
3551 issc->condition = besc;
3552 b->statements.push_back(issc);
3553 }
3554 else if (probe_type == kprobe_type)
3555 {
3556 // Generate: if (arg2 != kprobe_type) next;
3557 if_statement *istid = new if_statement;
3558 istid->thenblock = new next_statement;
3559 istid->elseblock = NULL;
3560 istid->tok = b->tok;
3561 comparison *betid = new comparison;
3562 betid->op = "!=";
3563 betid->tok = b->tok;
3564
3565 functioncall *arg2 = new functioncall;
3566 arg2->function = "ulong_arg";
3567 arg2->tok = b->tok;
3568 literal_number* num = new literal_number(2);
3569 num->tok = b->tok;
3570 arg2->args.push_back(num);
3571
3572 betid->left = arg2;
3573 literal_number* littid = new literal_number(kprobe_type);
3574 littid->tok = b->tok;
3575 betid->right = littid;
3576 istid->condition = betid;
3577 b->statements.push_back(istid);
3578 }
3579
3580 // Generate: if (arg1 != mark("label")) next;
3581 functioncall *fc = new functioncall;
3582 fc->function = (probe_type == utrace_type) ? "_utrace_syscall_arg" : "ulong_arg";
3583 fc->tok = b->tok;
3584 literal_number* num = new literal_number((probe_type == utrace_type) ? 0 : 1);
3585 num->tok = b->tok;
3586 fc->args.push_back(num);
3587
3588 functioncall *fcus = new functioncall;
3589 fcus->function = "user_string";
3590 fcus->type = pe_string;
3591 fcus->tok = b->tok;
3592 fcus->args.push_back(fc);
3593
3594 if_statement *is = new if_statement;
3595 is->thenblock = new next_statement;
3596 is->elseblock = NULL;
3597 is->tok = b->tok;
3598 comparison *be = new comparison;
3599 be->op = "!=";
3600 be->tok = b->tok;
3601 be->left = fcus;
3602 be->right = new literal_string(probe_name);
3603 is->condition = be;
3604 b->statements.push_back(is);
3605
3606 // Now replace the body
3607 b->statements.push_back(base->body);
3608 base->body = b;
3609}
3610
3611
3612void
3613sdt_query::convert_location (probe *base, probe_point *location)
3614{
3615 switch (probe_type)
3616 {
3617 case uprobe_type:
3618 if (sess.verbose > 3)
3619 clog << "probe_type == uprobe_type, use statement addr: 0x"
3620 << hex << probe_arg << dec << endl;
3621 // process("executable").statement(probe_arg)
3622 location->components[1]->functor = TOK_STATEMENT;
3623 location->components[1]->arg = new literal_number(probe_arg);
3624 break;
3625
3626 case kprobe_type:
3627 if (sess.verbose > 3)
3628 clog << "probe_type == kprobe_type" << endl;
3629 // kernel.function("*getegid*")
3630 location->components[0]->functor = TOK_KERNEL;
3631 location->components[0]->arg = NULL;
3632 location->components[1]->functor = TOK_FUNCTION;
3633 location->components[1]->arg = new literal_string("*getegid*");
3634 break;
3635
3636 case utrace_type:
3637 if (sess.verbose > 3)
3638 clog << "probe_type == utrace_type" << endl;
3639 // process("executable").syscall
3640 location->components[1]->functor = "syscall";
3641 location->components[1]->arg = NULL;
3642 break;
3643
3644 default:
3645 if (sess.verbose > 3)
3646 clog << "probe_type == use_uprobe_no_dwarf, use label name: "
3647 << "_stapprobe1_" << mark_name << endl;
3648 // process("executable").function("*").label("_stapprobe1_MARK_NAME")
3649 location->components[1]->functor = TOK_FUNCTION;
3650 location->components[1]->arg = new literal_string("*");
3651 location->components.push_back(new probe_point::component(TOK_LABEL));
3652 location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name);
3653 break;
3654 }
3655
3656 base->locations.clear();
3657 base->locations.push_back(location);
3658}
3659
3660
20c6c071 3661void
5227f1ea 3662dwarf_builder::build(systemtap_session & sess,
7a053d3b 3663 probe * base,
20c6c071 3664 probe_point * location,
86bf665e 3665 literal_map_t const & parameters,
20c6c071
GH
3666 vector<derived_probe *> & finished_results)
3667{
b20febf3
FCE
3668 // NB: the kernel/user dwlfpp objects are long-lived.
3669 // XXX: but they should be per-session, as this builder object
3670 // may be reused if we try to cross-instrument multiple targets.
84048984 3671
7a24d422
FCE
3672 dwflpp* dw = 0;
3673
7a24d422 3674 string module_name;
ae2552da
FCE
3675 if (has_null_param (parameters, TOK_KERNEL))
3676 {
3677 dw = get_kern_dw(sess, "kernel");
3678 }
3679 else if (get_param (parameters, TOK_MODULE, module_name))
b8da0ad1 3680 {
ae2552da 3681 dw = get_kern_dw(sess, module_name);
b8da0ad1 3682 }
7a24d422 3683 else if (get_param (parameters, TOK_PROCESS, module_name))
b8da0ad1 3684 {
d0a7f5a9
FCE
3685 module_name = find_executable (module_name); // canonicalize it
3686
7a24d422
FCE
3687 // user-space target; we use one dwflpp instance per module name
3688 // (= program or shared library)
707bf35e 3689 dw = get_user_dw(sess, module_name);
c8959a29 3690 }
20c6c071 3691
5896cd05
MW
3692 if (sess.verbose > 3)
3693 clog << "dwarf_builder::build for " << module_name << endl;
3694
3e1e31fb
JS
3695 string mark_name;
3696 if (get_param(parameters, TOK_MARK, mark_name))
7a05f484 3697 {
edce5b67
JS
3698 sdt_query sdtq(base, location, *dw, parameters, finished_results);
3699 dw->iterate_over_modules(&query_module, &sdtq);
3700 return;
7a05f484 3701 }
20c6c071 3702
edce5b67 3703 dwarf_query q(base, location, *dw, parameters, finished_results);
7a24d422
FCE
3704
3705 // XXX: kernel.statement.absolute is a special case that requires no
3706 // dwfl processing. This code should be in a separate builder.
7a24d422 3707 if (q.has_kernel && q.has_absolute)
37ebca01 3708 {
4baf0e53 3709 // assert guru mode for absolute probes
37ebca01
FCE
3710 if (! q.base_probe->privileged)
3711 {
edce5b67
JS
3712 throw semantic_error ("absolute statement probe in unprivileged script",
3713 q.base_probe->tok);
37ebca01
FCE
3714 }
3715
3716 // For kernel.statement(NUM).absolute probe points, we bypass
3717 // all the debuginfo stuff: We just wire up a
3718 // dwarf_derived_probe right here and now.
4baf0e53 3719 dwarf_derived_probe* p =
b8da0ad1
FCE
3720 new dwarf_derived_probe ("", "", 0, "kernel", "",
3721 q.statement_num_val, q.statement_num_val,
3722 q, 0);
37ebca01 3723 finished_results.push_back (p);
1a0dbc5a 3724 sess.unwindsym_modules.insert ("kernel");
37ebca01
FCE
3725 return;
3726 }
3727
51178501 3728 dw->iterate_over_modules(&query_module, &q);
5f0a03a6
JK
3729}
3730
3731symbol_table::~symbol_table()
3732{
1c6b77e5
JS
3733 for (iterator_t i = map_by_addr.begin(); i != map_by_addr.end(); ++i)
3734 delete i->second;
5f0a03a6
JK
3735}
3736
3737void
ab91b232
JK
3738symbol_table::add_symbol(const char *name, bool weak, Dwarf_Addr addr,
3739 Dwarf_Addr *high_addr)
5f0a03a6 3740{
ab91b232
JK
3741#ifdef __powerpc__
3742 // Map ".sys_foo" to "sys_foo".
3743 if (name[0] == '.')
3744 name++;
3745#endif
5f0a03a6
JK
3746 func_info *fi = new func_info();
3747 fi->addr = addr;
3748 fi->name = name;
ab91b232 3749 fi->weak = weak;
5f0a03a6
JK
3750 map_by_name[fi->name] = fi;
3751 // TODO: Use a multimap in case there are multiple static
3752 // functions with the same name?
1c6b77e5 3753 map_by_addr.insert(make_pair(addr, fi));
5f0a03a6
JK
3754}
3755
3756enum info_status
3757symbol_table::read_symbols(FILE *f, const string& path)
3758{
3759 // Based on do_kernel_symbols() in runtime/staprun/symbols.c
3760 int ret;
2e67a43b
TM
3761 char *name = 0;
3762 char *mod = 0;
5f0a03a6
JK
3763 char type;
3764 unsigned long long addr;
3765 Dwarf_Addr high_addr = 0;
3766 int line = 0;
3767
3768 // %as (non-POSIX) mallocs space for the string and stores its address.
3769 while ((ret = fscanf(f, "%llx %c %as [%as", &addr, &type, &name, &mod)) > 0)
3770 {
2e67a43b
TM
3771 auto_free free_name(name);
3772 auto_free free_mod(mod);
5f0a03a6
JK
3773 line++;
3774 if (ret < 3)
3775 {
41c262f3 3776 cerr << "Symbol table error: Line "
5f0a03a6
JK
3777 << line
3778 << " of symbol list from "
3779 << path
3780 << " is not in correct format: address type name [module]";
3781 // Caller should delete symbol_table object.
3782 return info_absent;
3783 }
2e67a43b 3784 else if (ret > 3)
5f0a03a6
JK
3785 {
3786 // Modules are loaded above the kernel, so if we're getting
3787 // modules, we're done.
2e67a43b 3788 break;
5f0a03a6 3789 }
ab91b232
JK
3790 if (type == 'T' || type == 't' || type == 'W')
3791 add_symbol(name, (type == 'W'), (Dwarf_Addr) addr, &high_addr);
5f0a03a6
JK
3792 }
3793
1c6b77e5 3794 if (map_by_addr.size() < 1)
5f0a03a6
JK
3795 {
3796 cerr << "Symbol table error: "
3797 << path << " contains no function symbols." << endl;
3798 return info_absent;
3799 }
3800 return info_present;
3801}
3802
3803// NB: This currently unused. We use get_from_elf() instead because
3804// that gives us raw addresses -- which we need for modules -- whereas
3805// nm provides the address relative to the beginning of the section.
3806enum info_status
83ca3872
MW
3807symbol_table::read_from_elf_file(const string &path,
3808 const systemtap_session &sess)
5f0a03a6
JK
3809{
3810 FILE *f;
3811 string cmd = string("/usr/bin/nm -n --defined-only ") + path;
3812 f = popen(cmd.c_str(), "r");
3813 if (!f)
3814 {
3815 // nm failures are detected by pclose, not popen.
3816 cerr << "Internal error reading symbol table from "
3817 << path << " -- " << strerror (errno);
3818 return info_absent;
3819 }
3820 enum info_status status = read_symbols(f, path);
3821 if (pclose(f) != 0)
3822 {
83ca3872 3823 if (status == info_present && ! sess.suppress_warnings)
5f0a03a6
JK
3824 cerr << "Warning: nm cannot read symbol table from " << path;
3825 return info_absent;
3826 }
3827 return status;
3828}
3829
3830enum info_status
83ca3872
MW
3831symbol_table::read_from_text_file(const string& path,
3832 const systemtap_session &sess)
5f0a03a6
JK
3833{
3834 FILE *f = fopen(path.c_str(), "r");
3835 if (!f)
3836 {
83ca3872
MW
3837 if (! sess.suppress_warnings)
3838 cerr << "Warning: cannot read symbol table from "
3839 << path << " -- " << strerror (errno);
5f0a03a6
JK
3840 return info_absent;
3841 }
3842 enum info_status status = read_symbols(f, path);
3843 (void) fclose(f);
3844 return status;
3845}
3846
46f7b6be
JK
3847void
3848symbol_table::prepare_section_rejection(Dwfl_Module *mod)
3849{
3850#ifdef __powerpc__
3851 /*
3852 * The .opd section contains function descriptors that can look
3853 * just like function entry points. For example, there's a function
3854 * descriptor called "do_exit" that links to the entry point ".do_exit".
3855 * Reject all symbols in .opd.
3856 */
3857 opd_section = SHN_UNDEF;
3858 Dwarf_Addr bias;
3859 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
3860 ?: dwfl_module_getelf (mod, &bias));
3861 Elf_Scn* scn = 0;
3862 size_t shstrndx;
3863
3864 if (!elf)
3865 return;
fcc30d6d 3866 if (elf_getshdrstrndx (elf, &shstrndx) != 0)
46f7b6be
JK
3867 return;
3868 while ((scn = elf_nextscn(elf, scn)) != NULL)
3869 {
3870 GElf_Shdr shdr_mem;
3871 GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
3872 if (!shdr)
3873 continue;
3874 const char *name = elf_strptr(elf, shstrndx, shdr->sh_name);
3875 if (!strcmp(name, ".opd"))
3876 {
3877 opd_section = elf_ndxscn(scn);
3878 return;
3879 }
3880 }
3881#endif
3882}
3883
3884bool
3885symbol_table::reject_section(GElf_Word section)
3886{
3887 if (section == SHN_UNDEF)
3888 return true;
3889#ifdef __powerpc__
3890 if (section == opd_section)
3891 return true;
3892#endif
3893 return false;
3894}
3895
5f0a03a6
JK
3896enum info_status
3897symbol_table::get_from_elf()
3898{
3899 Dwarf_Addr high_addr = 0;
3900 Dwfl_Module *mod = mod_info->mod;
3901 int syments = dwfl_module_getsymtab(mod);
3902 assert(syments);
46f7b6be 3903 prepare_section_rejection(mod);
5f0a03a6
JK
3904 for (int i = 1; i < syments; ++i)
3905 {
3906 GElf_Sym sym;
ab91b232
JK
3907 GElf_Word section;
3908 const char *name = dwfl_module_getsym(mod, i, &sym, &section);
46f7b6be
JK
3909 if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC &&
3910 !reject_section(section))
ab91b232
JK
3911 add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
3912 sym.st_value, &high_addr);
5f0a03a6
JK
3913 }
3914 return info_present;
3915}
3916
5f0a03a6
JK
3917func_info *
3918symbol_table::get_func_containing_address(Dwarf_Addr addr)
3919{
1c6b77e5
JS
3920 iterator_t iter = map_by_addr.upper_bound(addr);
3921 if (iter == map_by_addr.begin())
5f0a03a6 3922 return NULL;
2e67a43b 3923 else
1c6b77e5 3924 return (--iter)->second;
5f0a03a6
JK
3925}
3926
3927func_info *
3928symbol_table::lookup_symbol(const string& name)
3929{
3930 map<string, func_info*>::iterator i = map_by_name.find(name);
3931 if (i == map_by_name.end())
3932 return NULL;
3933 return i->second;
3934}
3935
3936Dwarf_Addr
3937symbol_table::lookup_symbol_address(const string& name)
3938{
3939 func_info *fi = lookup_symbol(name);
3940 if (fi)
3941 return fi->addr;
3942 return 0;
3943}
3944
ab91b232
JK
3945// This is the kernel symbol table. The kernel macro cond_syscall creates
3946// a weak symbol for each system call and maps it to sys_ni_syscall.
3947// For system calls not implemented elsewhere, this weak symbol shows up
3948// in the kernel symbol table. Following the precedent of dwarfful stap,
3949// we refuse to consider such symbols. Here we delete them from our
3950// symbol table.
3951// TODO: Consider generalizing this and/or making it part of blacklist
3952// processing.
3953void
3954symbol_table::purge_syscall_stubs()
3955{
3956 Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
3957 if (stub_addr == 0)
3958 return;
1c6b77e5 3959 range_t purge_range = map_by_addr.equal_range(stub_addr);
2e67a43b
TM
3960 for (iterator_t iter = purge_range.first;
3961 iter != purge_range.second;
1c6b77e5 3962 )
ab91b232 3963 {
1c6b77e5 3964 func_info *fi = iter->second;
2e67a43b 3965 if (fi->weak && fi->name != "sys_ni_syscall")
ab91b232 3966 {
2e67a43b 3967 map_by_name.erase(fi->name);
1c6b77e5 3968 map_by_addr.erase(iter++);
2e67a43b 3969 delete fi;
2e67a43b 3970 }
1c6b77e5
JS
3971 else
3972 iter++;
ab91b232
JK
3973 }
3974}
3975
5f0a03a6
JK
3976void
3977module_info::get_symtab(dwarf_query *q)
3978{
3979 systemtap_session &sess = q->sess;
3980
1c6b77e5
JS
3981 if (symtab_status != info_unknown)
3982 return;
3983
5f0a03a6
JK
3984 sym_table = new symbol_table(this);
3985 if (!elf_path.empty())
3986 {
83ca3872
MW
3987 if (name == TOK_KERNEL && !sess.kernel_symtab_path.empty()
3988 && ! sess.suppress_warnings)
5f0a03a6
JK
3989 cerr << "Warning: reading symbol table from "
3990 << elf_path
3991 << " -- ignoring "
3992 << sess.kernel_symtab_path
83ca3872 3993 << endl;
5f0a03a6
JK
3994 symtab_status = sym_table->get_from_elf();
3995 }
3996 else
3997 {
3998 assert(name == TOK_KERNEL);
3999 if (sess.kernel_symtab_path.empty())
4000 {
4001 symtab_status = info_absent;
4002 cerr << "Error: Cannot find vmlinux."
4003 << " Consider using --kmap instead of --kelf."
4004 << endl;;
4005 }
4006 else
4007 {
4008 symtab_status =
83ca3872 4009 sym_table->read_from_text_file(sess.kernel_symtab_path, sess);
5f0a03a6
JK
4010 if (symtab_status == info_present)
4011 {
4012 sess.sym_kprobes_text_start =
4013 sym_table->lookup_symbol_address("__kprobes_text_start");
4014 sess.sym_kprobes_text_end =
4015 sym_table->lookup_symbol_address("__kprobes_text_end");
4016 sess.sym_stext = sym_table->lookup_symbol_address("_stext");
5f0a03a6
JK
4017 }
4018 }
4019 }
4020 if (symtab_status == info_absent)
4021 {
4022 delete sym_table;
4023 sym_table = NULL;
4024 return;
4025 }
4026
ab91b232
JK
4027 if (name == TOK_KERNEL)
4028 sym_table->purge_syscall_stubs();
5f0a03a6
JK
4029}
4030
1c6b77e5
JS
4031// update_symtab reconciles data between the elf symbol table and the dwarf
4032// function enumeration. It updates the symbol table entries with the dwarf
4033// die that describes the function, which also signals to query_module_symtab
4034// that a statement probe isn't needed. In return, it also adds aliases to the
4035// function table for names that share the same addr/die.
4036void
4037module_info::update_symtab(cu_function_cache_t *funcs)
4038{
4039 if (!sym_table)
4040 return;
4041
4042 cu_function_cache_t new_funcs;
4043
4044 for (cu_function_cache_t::iterator func = funcs->begin();
4045 func != funcs->end(); func++)
4046 {
4047 // optimization: inlines will never be in the symbol table
4048 if (dwarf_func_inline(&func->second) != 0)
4049 continue;
4050
4051 func_info *fi = sym_table->lookup_symbol(func->first);
4052 if (!fi)
4053 continue;
4054
4055 // iterate over all functions at the same address
4056 symbol_table::range_t er = sym_table->map_by_addr.equal_range(fi->addr);
4057 for (symbol_table::iterator_t it = er.first; it != er.second; ++it)
4058 {
4059 // update this function with the dwarf die
4060 it->second->die = func->second;
4061
4062 // if this function is a new alias, then
4063 // save it to merge into the function cache
4064 if (it->second != fi)
4065 new_funcs[it->second->name] = it->second->die;
4066 }
4067 }
4068
4069 // add all discovered aliases back into the function cache
4070 // NB: this won't replace any names that dwarf may have already found
4071 funcs->insert(new_funcs.begin(), new_funcs.end());
4072}
4073
5f0a03a6
JK
4074module_info::~module_info()
4075{
4076 if (sym_table)
4077 delete sym_table;
b55bc428
FCE
4078}
4079
888af770
FCE
4080// ------------------------------------------------------------------------
4081// user-space probes
4082// ------------------------------------------------------------------------
4083
888af770
FCE
4084
4085struct uprobe_derived_probe_group: public generic_dpg<uprobe_derived_probe>
4086{
4087public:
4088 void emit_module_decls (systemtap_session& s);
4089 void emit_module_init (systemtap_session& s);
4090 void emit_module_exit (systemtap_session& s);
4091};
4092
4093
6d0f3f0c
FCE
4094uprobe_derived_probe::uprobe_derived_probe (const string& function,
4095 const string& filename,
4096 int line,
4097 const string& module,
4098 int pid,
4099 const string& section,
4100 Dwarf_Addr dwfl_addr,
4101 Dwarf_Addr addr,
4102 dwarf_query & q,
4103 Dwarf_Die* scope_die /* may be null */):
4104 derived_probe (q.base_probe, new probe_point (*q.base_loc) /* .components soon rewritten */ ),
4105 return_p (q.has_return), module (module), pid (pid), section (section), address (addr)
4baf0e53 4106{
17c128f2
FCE
4107 // We may receive probes on two types of ELF objects: ET_EXEC or ET_DYN.
4108 // ET_EXEC ones need no further relocation on the addr(==dwfl_addr), whereas
4109 // ET_DYN ones do (addr += run-time mmap base address). We tell these apart
4110 // by the incoming section value (".absolute" vs. ".dynamic").
6d0f3f0c
FCE
4111
4112 this->tok = q.base_probe->tok;
4113
de688825 4114 // Expand target variables in the probe body
6d0f3f0c
FCE
4115 if (!null_die(scope_die))
4116 {
de688825 4117 dwarf_var_expanding_visitor v (q, scope_die, dwfl_addr); // XXX: user-space deref's!
4ed05b15 4118 this->body = v.require (this->body);
6d0f3f0c
FCE
4119
4120 // If during target-variable-expanding the probe, we added a new block
4121 // of code, add it to the start of the probe.
4122 if (v.add_block)
4123 this->body = new block(v.add_block, this->body);
4124
4125 // If when target-variable-expanding the probe, we added a new
4126 // probe, add it in a new file to the list of files to be processed.
4127 if (v.add_probe)
4128 {
4129 stapfile *f = new stapfile;
4130 f->probes.push_back(v.add_probe);
4131 q.sess.files.push_back(f);
4132 }
4133 }
4134 // else - null scope_die - $target variables will produce an error during translate phase
4135
9ace370f
JS
4136 // Save the local variables for listing mode
4137 if (q.sess.listing_mode_vars)
4138 saveargs(scope_die);
4139
6d0f3f0c
FCE
4140 // Reset the sole element of the "locations" vector as a
4141 // "reverse-engineered" form of the incoming (q.base_loc) probe
4142 // point. This allows a user to see what function / file / line
4143 // number any particular match of the wildcards.
4144
4145 vector<probe_point::component*> comps;
4146 if(q.has_process)
4147 comps.push_back (new probe_point::component(TOK_PROCESS, new literal_string(module)));
4148 else
4149 assert (0);
06aca46a 4150
6d0f3f0c
FCE
4151 string fn_or_stmt;
4152 if (q.has_function_str || q.has_function_num)
4153 fn_or_stmt = "function";
4154 else
4155 fn_or_stmt = "statement";
4156
4157 if (q.has_function_str || q.has_statement_str)
4158 {
4159 string retro_name = function;
4160 if (filename != "")
fb84c077
FCE
4161 {
4162 retro_name += ("@" + string (filename));
4163 if (line > 0)
4164 retro_name += (":" + lex_cast<string> (line));
4165 }
6d0f3f0c
FCE
4166 comps.push_back
4167 (new probe_point::component
4168 (fn_or_stmt, new literal_string (retro_name)));
4169 }
4170 else if (q.has_function_num || q.has_statement_num)
4171 {
4172 Dwarf_Addr retro_addr;
4173 if (q.has_function_num)
4174 retro_addr = q.function_num_val;
4175 else
4176 retro_addr = q.statement_num_val;
4177 comps.push_back (new probe_point::component
4178 (fn_or_stmt,
4179 new literal_number(retro_addr))); // XXX: should be hex if possible
4180
4181 if (q.has_absolute)
4182 comps.push_back (new probe_point::component (TOK_ABSOLUTE));
4183 }
4184
4185 if (q.has_call)
4186 comps.push_back (new probe_point::component(TOK_CALL));
4187 if (q.has_inline)
4188 comps.push_back (new probe_point::component(TOK_INLINE));
4189 if (return_p)
4190 comps.push_back (new probe_point::component(TOK_RETURN));
4191 /*
4192 if (has_maxactive)
4193 comps.push_back (new probe_point::component
4194 (TOK_MAXACTIVE, new literal_number(maxactive_val)));
4195 */
4196
4197 // Overwrite it.
4198 this->sole_location()->components = comps;
4199}
4200
4201
0973d815
FCE
4202uprobe_derived_probe::uprobe_derived_probe (probe *base,
4203 probe_point *location,
4204 int pid,
4205 Dwarf_Addr addr,
4206 bool has_return):
4207 derived_probe (base, location), // location is not rewritten here
4208 return_p (has_return), pid (pid), address (addr)
4209{
4210}
4211
4212
9ace370f
JS
4213void
4214uprobe_derived_probe::saveargs(Dwarf_Die* scope_die)
4215{
4216 // same as dwarf_derived_probe::saveargs
4217
4218 Dwarf_Die *scopes;
4219 if (!null_die(scope_die) && dwarf_getscopes_die (scope_die, &scopes) == 0)
4220 return;
4221 auto_free free_scopes(scopes);
4222
4223 stringstream argstream;
4224 string type_name;
4225 Dwarf_Attribute type_attr;
4226 Dwarf_Die type_die;
4227
4228 if (return_p &&
4229 dwarf_attr_integrate (scope_die, DW_AT_type, &type_attr) &&
4230 dwarf_formref_die (&type_attr, &type_die) &&
4231 dwarf_type_name(type_die, type_name))
4232 argstream << " $return:" << type_name;
4233
4234 Dwarf_Die arg;
4235 if (dwarf_child (&scopes[0], &arg) == 0)
4236 do
4237 {
4238 switch (dwarf_tag (&arg))
4239 {
4240 case DW_TAG_variable:
4241 case DW_TAG_formal_parameter:
4242 break;
4243
4244 default:
4245 continue;
4246 }
4247
4248 const char *arg_name = dwarf_diename (&arg);
4249 if (!arg_name)
4250 continue;
4251
4252 type_name.clear();
4253 if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) ||
4254 !dwarf_formref_die (&type_attr, &type_die) ||
4255 !dwarf_type_name(type_die, type_name))
4256 continue;
4257
4258 argstream << " $" << arg_name << ":" << type_name;
4259 }
4260 while (dwarf_siblingof (&arg, &arg) == 0);
4261
4262 args = argstream.str();
4263}
4264
4265
4266void
4267uprobe_derived_probe::printargs(std::ostream &o) const
4268{
4269 // same as dwarf_derived_probe::printargs
4270 o << args;
4271}
4272
4273
6d0f3f0c
FCE
4274void
4275uprobe_derived_probe::printsig (ostream& o) const
4276{
4277 // Same as dwarf_derived_probe.
4278 sole_location()->print (o);
4279 o << " /* pc=" << section << "+0x" << hex << address << dec << " */";
4280 printsig_nested (o);
888af770
FCE
4281}
4282
4283
4284void
4285uprobe_derived_probe::join_group (systemtap_session& s)
4286{
4287 if (! s.uprobe_derived_probes)
4288 s.uprobe_derived_probes = new uprobe_derived_probe_group ();
4289 s.uprobe_derived_probes->enroll (this);
93646f4d 4290 enable_task_finder(s);
8a03658e
JS
4291
4292 // Ask buildrun.cxx to build extra module if needed, and
4293 // signal staprun to load that module
4294 s.need_uprobes = true;
888af770
FCE
4295}
4296
4297
4298struct uprobe_builder: public derived_probe_builder
4299{
4300 uprobe_builder() {}
4301 virtual void build(systemtap_session & sess,
4302 probe * base,
4303 probe_point * location,
86bf665e 4304 literal_map_t const & parameters,
888af770
FCE
4305 vector<derived_probe *> & finished_results)
4306 {
4307 int64_t process, address;
4308
4309 bool b1 = get_param (parameters, TOK_PROCESS, process);
ced347a9 4310 (void) b1;
888af770 4311 bool b2 = get_param (parameters, TOK_STATEMENT, address);
ced347a9 4312 (void) b2;
888af770
FCE
4313 bool rr = has_null_param (parameters, TOK_RETURN);
4314 assert (b1 && b2); // by pattern_root construction
4baf0e53 4315
0973d815 4316 finished_results.push_back(new uprobe_derived_probe(base, location, process, address, rr));
888af770
FCE
4317 }
4318};
4319
4320
4321void
775d51e5 4322uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
888af770
FCE
4323{
4324 if (probes.empty()) return;
775d51e5 4325 s.op->newline() << "/* ---- user probes ---- */";
4baf0e53 4326
c480bf3d 4327 // If uprobes isn't in the kernel, pull it in from the runtime.
6274464e 4328 s.op->newline() << "#if defined(CONFIG_UPROBES) || defined(CONFIG_UPROBES_MODULE)";
888af770 4329 s.op->newline() << "#include <linux/uprobes.h>";
c480bf3d 4330 s.op->newline() << "#else";
6274464e 4331 s.op->newline() << "#include \"uprobes/uprobes.h\"";
c480bf3d 4332 s.op->newline() << "#endif";
9d451878
JK
4333 s.op->newline() << "#ifndef UPROBES_API_VERSION";
4334 s.op->newline() << "#define UPROBES_API_VERSION 1";
4335 s.op->newline() << "#endif";
6d0f3f0c 4336
01b05e2e 4337 s.op->newline() << "#ifndef MULTIPLE_UPROBES";
478c850f
FCE
4338 s.op->newline() << "#define MULTIPLE_UPROBES 256"; // maximum possible armed uprobes per process() probe point
4339 // or apprx. max number of processes mapping a shared library
01b05e2e 4340 s.op->newline() << "#endif";
6d0f3f0c 4341 s.op->newline() << "#ifndef MAXUPROBES";
01b05e2e 4342 s.op->newline() << "#define MAXUPROBES (MULTIPLE_UPROBES * " << probes.size() << ")";
6d0f3f0c 4343 s.op->newline() << "#endif";
888af770 4344
5e112f92
FCE
4345 // In .bss, the shared pool of uprobe/uretprobe structs. These are
4346 // too big to embed in the initialized .data stap_uprobe_spec array.
4c2732a1 4347 s.op->newline() << "static struct stap_uprobe {";
888af770 4348 s.op->newline(1) << "union { struct uprobe up; struct uretprobe urp; };";
6d0f3f0c 4349 s.op->newline() << "int spec_index;"; // index into stap_uprobe_specs; <0 == free && unregistered
01b05e2e 4350 s.op->newline(-1) << "} stap_uprobes [MAXUPROBES];";
5e112f92 4351 s.op->newline() << "DEFINE_MUTEX(stap_uprobes_lock);"; // protects against concurrent registration/unregistration
6d0f3f0c 4352
c9a05b1c 4353 // Emit vma callbacks.
dd163639 4354 s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
c9a05b1c
MW
4355 s.op->newline() << "static struct stap_task_finder_target stap_uprobe_vmcbs[] = {";
4356 s.op->indent(1);
4357 for (unsigned i = 0; i < probes.size(); i++)
4358 {
4359 uprobe_derived_probe* p = probes[i];
4360 if (p->pid != 0)
4361 emit_vma_callback_probe_decl (s, "", p->pid);
4362 else
4363 emit_vma_callback_probe_decl (s, p->module, (int64_t)0);
4364 }
4365 s.op->newline(-1) << "};";
dd163639 4366 s.op->newline() << "#endif";
c9a05b1c 4367
4c2732a1 4368 s.op->newline() << "static struct stap_uprobe_spec {";
5e112f92 4369 s.op->newline(1) << "struct stap_task_finder_target finder;";
888af770 4370 s.op->newline() << "unsigned long address;";
17c128f2 4371 s.op->newline() << "const char *pathname;";
888af770
FCE
4372 s.op->newline() << "const char *pp;";
4373 s.op->newline() << "void (*ph) (struct context*);";
6d0f3f0c
FCE
4374 s.op->newline() << "unsigned return_p:1;";
4375 s.op->newline(-1) << "} stap_uprobe_specs [] = {";
888af770
FCE
4376 s.op->indent(1);
4377 for (unsigned i =0; i<probes.size(); i++)
4378 {
4379 uprobe_derived_probe* p = probes[i];
4380 s.op->newline() << "{";
0973d815
FCE
4381 s.op->line() << " .finder = {";
4382 if (p->pid != 0)
17c128f2
FCE
4383 s.op->line() << " .pid=" << p->pid;
4384 else if (p->section == ".absolute")
0973d815 4385 s.op->line() << " .pathname=" << lex_cast_qstring(p->module) << ", ";
06aca46a 4386 // else ".dynamic" gets pathname=0, pid=0, activating task_finder "global tracing"
0973d815 4387 s.op->line() << "},";
17c128f2
FCE
4388 if (p->section != ".absolute")
4389 s.op->line() << " .pathname=" << lex_cast_qstring(p->module) << ", ";
dc38c256 4390 s.op->line() << " .address=(unsigned long)0x" << hex << p->address << dec << "ULL,";
888af770
FCE
4391 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
4392 s.op->line() << " .ph=&" << p->name << ",";
4393 if (p->return_p) s.op->line() << " .return_p=1,";
4394 s.op->line() << " },";
4395 }
4396 s.op->newline(-1) << "};";
4397
48e685da 4398 s.op->newline() << "static void enter_uprobe_probe (struct uprobe *inst, struct pt_regs *regs) {";
888af770 4399 s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);";
6d0f3f0c 4400 s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
c12d974f 4401 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp");
6d0f3f0c
FCE
4402 s.op->newline() << "if (sup->spec_index < 0 ||"
4403 << "sup->spec_index >= " << probes.size() << ") return;"; // XXX: should not happen
888af770 4404 s.op->newline() << "c->regs = regs;";
6415ddde
MW
4405
4406 // Make it look like the IP is set as it would in the actual user
4407 // task when calling real probe handler. Reset IP regs on return, so
4408 // we don't confuse uprobes. PR10458
4409 s.op->newline() << "{";
4410 s.op->indent(1);
4411 s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->regs);";
4412 s.op->newline() << "REG_IP(regs) = inst->vaddr;";
6d0f3f0c 4413 s.op->newline() << "(*sups->ph) (c);";
6415ddde
MW
4414 s.op->newline() << "REG_IP(regs) = uprobes_ip;";
4415 s.op->newline(-1) << "}";
4416
888af770
FCE
4417 common_probe_entryfn_epilogue (s.op);
4418 s.op->newline(-1) << "}";
4419
48e685da 4420 s.op->newline() << "static void enter_uretprobe_probe (struct uretprobe_instance *inst, struct pt_regs *regs) {";
888af770 4421 s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);";
6d0f3f0c 4422 s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
c12d974f 4423 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sups->pp");
6d0f3f0c
FCE
4424 s.op->newline() << "if (sup->spec_index < 0 ||"
4425 << "sup->spec_index >= " << probes.size() << ") return;"; // XXX: should not happen
888af770
FCE
4426 // XXX: kretprobes saves "c->pi = inst;" too
4427 s.op->newline() << "c->regs = regs;";
6415ddde
MW
4428
4429 // Make it look like the IP is set as it would in the actual user
4430 // task when calling real probe handler. Reset IP regs on return, so
4431 // we don't confuse uprobes. PR10458
4432 s.op->newline() << "{";
4433 s.op->indent(1);
4434 s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->regs);";
4435 s.op->newline() << "REG_IP(regs) = inst->rp->u.vaddr;";
6d0f3f0c 4436 s.op->newline() << "(*sups->ph) (c);";
6415ddde
MW
4437 s.op->newline() << "REG_IP(regs) = uprobes_ip;";
4438 s.op->newline(-1) << "}";
4439
888af770
FCE
4440 common_probe_entryfn_epilogue (s.op);
4441 s.op->newline(-1) << "}";
6d0f3f0c 4442
17c128f2
FCE
4443
4444
6d0f3f0c
FCE
4445 // NB: Because these utrace callbacks only occur before / after
4446 // userspace instructions run, there is no concurrency control issue
4447 // between active uprobe callbacks and these registration /
06aca46a 4448 // unregistration pieces.
6d0f3f0c
FCE
4449
4450 // We protect the stap_uprobe->spec_index (which also serves as a
d41d451c
FCE
4451 // free/busy flag) value with the outer protective stap_probes_lock
4452 // spinlock, to protect it against concurrent registration /
4453 // unregistration.
6d0f3f0c
FCE
4454
4455 s.op->newline();
17c128f2
FCE
4456 s.op->newline() << "static int stap_uprobe_change (struct task_struct *tsk, int register_p, unsigned long relocation, struct stap_uprobe_spec *sups) {";
4457 s.op->newline(1) << "int spec_index = (sups - stap_uprobe_specs);";
6d0f3f0c 4458 s.op->newline() << "int handled_p = 0;";
d41d451c 4459 s.op->newline() << "int slotted_p = 0;";
6d0f3f0c
FCE
4460 s.op->newline() << "int rc = 0;";
4461 s.op->newline() << "int i;";
3568f1dd 4462
d41d451c 4463 s.op->newline() << "mutex_lock (& stap_uprobes_lock);";
01b05e2e 4464 s.op->newline() << "for (i=0; i<MAXUPROBES; i++) {"; // XXX: slow linear search
5e112f92 4465 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
6d0f3f0c
FCE
4466
4467 // register new uprobe
4468 s.op->newline() << "if (register_p && sup->spec_index < 0) {";
9d451878
JK
4469 s.op->newline(1) << "#if (UPROBES_API_VERSION < 2)";
4470 // See PR6829 comment.
4471 s.op->newline() << "if (sup->spec_index == -1 && sup->up.kdata != NULL) continue;";
80b4ad8b 4472 s.op->newline() << "else if (sup->spec_index == -2 && sup->urp.u.kdata != NULL) continue;";
9d451878 4473 s.op->newline() << "#endif";
80b4ad8b 4474 s.op->newline() << "sup->spec_index = spec_index;";
d41d451c
FCE
4475 s.op->newline() << "slotted_p = 1;";
4476 s.op->newline() << "break;";
4477 s.op->newline(-1) << "} else if (!register_p && "
4478 << "sup->spec_index == spec_index && " // a u[ret]probe set up for this probe point
4479 << "((sups->return_p && sup->urp.u.pid == tsk->tgid && sup->urp.u.vaddr == relocation + sups->address) ||" // dying uretprobe
4480 << "(!sups->return_p && sup->up.pid == tsk->tgid && sup->up.vaddr == relocation + sups->address))) {"; // dying uprobe
4481 s.op->newline(1) << "slotted_p = 1;";
4482 s.op->newline() << "break;"; // exit to-free slot search
4483 s.op->newline(-1) << "}";
4484
4485 s.op->newline(-1) << "}";
4486 s.op->newline() << "mutex_unlock (& stap_uprobes_lock);";
4487
4488 s.op->newline() << "#ifdef DEBUG_UPROBES";
4489 s.op->newline() << "printk (KERN_INFO \"%cuprobe spec %d idx %d process %s[%d] reloc %p pp '%s'\\n\", ";
4490 s.op->line() << "(register_p ? '+' : '-'), spec_index, (slotted_p ? i : -1), tsk->comm, tsk->tgid, (void*) relocation, sups->pp);";
4491 s.op->newline() << "#endif";
4492
4493 // Here, slotted_p implies that `i' points to the single
4494 // stap_uprobes[] element that has been slotted in for registration
4495 // or unregistration processing. !slotted_p implies that the table
4496 // was full (registration; MAXUPROBES) or that no matching entry was
4497 // found (unregistration; should not happen).
4498
4499 s.op->newline() << "if (register_p && slotted_p) {";
4500 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
6d0f3f0c
FCE
4501 s.op->newline() << "if (sups->return_p) {";
4502 s.op->newline(1) << "sup->urp.u.pid = tsk->tgid;";
17c128f2 4503 s.op->newline() << "sup->urp.u.vaddr = relocation + sups->address;";
6d0f3f0c
FCE
4504 s.op->newline() << "sup->urp.handler = &enter_uretprobe_probe;";
4505 s.op->newline() << "rc = register_uretprobe (& sup->urp);";
4506 s.op->newline(-1) << "} else {";
4507 s.op->newline(1) << "sup->up.pid = tsk->tgid;";
17c128f2 4508 s.op->newline() << "sup->up.vaddr = relocation + sups->address;";
6d0f3f0c
FCE
4509 s.op->newline() << "sup->up.handler = &enter_uprobe_probe;";
4510 s.op->newline() << "rc = register_uprobe (& sup->up);";
4511 s.op->newline(-1) << "}";
6d0f3f0c 4512 s.op->newline() << "if (rc) {"; // failed to register
d41d451c
FCE
4513 s.op->newline(1) << "printk (KERN_WARNING \"uprobe failed %s[%d] '%s' addr %p rc %d\\n\", tsk->comm, tsk->tgid, sups->pp, (void*)(relocation + sups->address), rc);";
4514 // NB: we need to release this slot, so we need to borrow the mutex temporarily.
4515 s.op->newline() << "mutex_lock (& stap_uprobes_lock);";
3568f1dd 4516 s.op->newline() << "sup->spec_index = -1;";
d41d451c 4517 s.op->newline() << "mutex_unlock (& stap_uprobes_lock);";
6d0f3f0c
FCE
4518 s.op->newline(-1) << "} else {";
4519 s.op->newline(1) << "handled_p = 1;"; // success
4520 s.op->newline(-1) << "}";
6d0f3f0c 4521
d41d451c
FCE
4522 s.op->newline(-1) << "} else if (!register_p && slotted_p) {";
4523 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
9d451878
JK
4524 s.op->newline() << "int unregistered_flag;";
4525 // PR6829, PR9940:
4526 // Here we're unregistering for one of two reasons:
4527 // 1. the process image is going away (or gone) due to exit or exec; or
4528 // 2. the vma containing the probepoint has been unmapped.
4529 // In case 1, it's sort of a nop, because uprobes will notice the event
4530 // and dispose of the probes eventually, if it hasn't already. But by
4531 // calling unmap_u[ret]probe() ourselves, we free up sup right away.
4532 //
4533 // In both cases, we must use unmap_u[ret]probe instead of
4534 // unregister_u[ret]probe, so uprobes knows not to try to restore the
4535 // original opcode.
4536 s.op->newline() << "#if (UPROBES_API_VERSION >= 2)";
4537 s.op->newline() << "if (sups->return_p)";
4538 s.op->newline(1) << "unmap_uretprobe (& sup->urp);";
4539 s.op->newline(-1) << "else";
4540 s.op->newline(1) << "unmap_uprobe (& sup->up);";
4541 s.op->newline(-1) << "unregistered_flag = -1;";
4542 s.op->newline() << "#else";
4543 // Uprobes lacks unmap_u[ret]probe. Before reusing sup, we must wait
4544 // until uprobes turns loose of the u[ret]probe on its own, as indicated
4545 // by uprobe.kdata = NULL.
4546 s.op->newline() << "unregistered_flag = (sups->return_p ? -2 : -1);";
4547 s.op->newline() << "#endif";
d41d451c 4548 s.op->newline() << "mutex_lock (& stap_uprobes_lock);";
9d451878 4549 s.op->newline() << "sup->spec_index = unregistered_flag;";
5e112f92 4550 s.op->newline() << "mutex_unlock (& stap_uprobes_lock);";
d41d451c
FCE
4551 s.op->newline() << "handled_p = 1;";
4552 s.op->newline(-1) << "}"; // if slotted_p
4553
4554 // NB: handled_p implies slotted_p
4555
6d0f3f0c 4556 s.op->newline() << "if (! handled_p) {";
73209876
FCE
4557 s.op->newline(1) << "#ifdef STP_TIMING";
4558 s.op->newline() << "atomic_inc (register_p ? & skipped_count_uprobe_reg : & skipped_count_uprobe_unreg);";
4559 s.op->newline() << "#endif";
4560 // NB: duplicates common_entryfn_epilogue, but then this is not a probe entry fn epilogue.
4561 s.op->newline() << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
6d0f3f0c
FCE
4562 s.op->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
4563 s.op->newline() << "_stp_exit ();";
4564 s.op->newline(-1) << "}";
4565 s.op->newline(-1) << "}";
06aca46a 4566
6d0f3f0c
FCE
4567 s.op->newline() << "return 0;"; // XXX: or rc?
4568 s.op->newline(-1) << "}";
4569 s.op->assert_0_indent();
4570
17c128f2
FCE
4571
4572 // The task_finder_callback we use for ET_EXEC targets.
4573 s.op->newline();
4574 s.op->newline() << "static int stap_uprobe_process_found (struct stap_task_finder_target *tgt, struct task_struct *tsk, int register_p, int process_p) {";
4575
4576 s.op->newline(1) << "struct stap_uprobe_spec *sups = container_of(tgt, struct stap_uprobe_spec, finder);";
4577 s.op->newline() << "if (! process_p) return 0;";
4578 s.op->newline(0) << "return stap_uprobe_change (tsk, register_p, 0, sups);";
4579 s.op->newline(-1) << "}";
4580
782040b3 4581 // The task_finder_mmap_callback we use for ET_DYN targets.
17c128f2 4582 s.op->newline();
782040b3 4583 s.op->newline() << "static int stap_uprobe_mmap_found (struct stap_task_finder_target *tgt, struct task_struct *tsk, char *path, unsigned long addr, unsigned long length, unsigned long offset, unsigned long vm_flags) {";
17c128f2
FCE
4584 s.op->newline(1) << "struct stap_uprobe_spec *sups = container_of(tgt, struct stap_uprobe_spec, finder);";
4585 // 1 - shared libraries' executable segments load from offset 0 - ld.so convention
782040b3 4586 s.op->newline() << "if (offset != 0) return 0;";
17c128f2 4587 // 2 - the shared library we're interested in
782040b3 4588 s.op->newline() << "if (path == NULL || strcmp (path, sups->pathname)) return 0;";
17c128f2 4589 // 3 - probe address within the mapping limits; test should not fail
782040b3
DS
4590 s.op->newline() << "if (sups->address >= addr && sups->address < (addr + length)) return 0;";
4591 // 4 - mapping should be executable
4592 s.op->newline() << "if (!(vm_flags & VM_EXEC)) return 0;";
06aca46a 4593
c16d425a 4594 s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
782040b3 4595 s.op->newline() << "printk (KERN_INFO \"vmchange pid %d path %s addr %p length %lu offset %p\\n\", tsk->tgid, path, (void *) addr, length, (void*) offset);";
c16d425a
FCE
4596 s.op->newline() << "printk (KERN_INFO \"sups %p pp %s path %s address %p\\n\", sups, sups->pp, sups->pathname ?: \"\", (void*) sups->address);";
4597 s.op->newline() << "#endif";
4598
782040b3 4599 s.op->newline(0) << "return stap_uprobe_change (tsk, 1, addr, sups);";
17c128f2
FCE
4600 s.op->newline(-1) << "}";
4601 s.op->assert_0_indent();
4602
4603
6d0f3f0c 4604 s.op->newline();
888af770
FCE
4605}
4606
4607
4608void
4609uprobe_derived_probe_group::emit_module_init (systemtap_session& s)
4610{
4611 if (probes.empty()) return;
dd163639 4612 s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER";
782040b3 4613 s.op->newline() << "_stp_sym_init();";
c9a05b1c
MW
4614 s.op->newline() << "/* ---- uprobe vma callbacks ---- */";
4615 s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_uprobe_vmcbs); i++) {";
4616 s.op->indent(1);
4617 s.op->newline() << "struct stap_task_finder_target *r = &stap_uprobe_vmcbs[i];";
4618 s.op->newline() << "rc = stap_register_task_finder_target(r);";
4619 s.op->newline(-1) << "}";
dd163639 4620 s.op->newline() << "#endif";
c9a05b1c 4621
5e112f92
FCE
4622 s.op->newline() << "/* ---- user probes ---- */";
4623
01b05e2e 4624 s.op->newline() << "for (j=0; j<MAXUPROBES; j++) {";
5e112f92
FCE
4625 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[j];";
4626 s.op->newline() << "sup->spec_index = -1;"; // free slot
80b4ad8b
FCE
4627 // NB: we assume the rest of the struct (specificaly, sup->up) is
4628 // initialized to zero. This is so that we can use
4629 // sup->up->kdata = NULL for "really free!" PR 6829.
5e112f92
FCE
4630 s.op->newline(-1) << "}";
4631 s.op->newline() << "mutex_init (& stap_uprobes_lock);";
888af770
FCE
4632
4633 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
6d0f3f0c
FCE
4634 s.op->newline(1) << "struct stap_uprobe_spec *sups = & stap_uprobe_specs[i];";
4635 s.op->newline() << "probe_point = sups->pp;"; // for error messages
17c128f2 4636 s.op->newline() << "if (sups->finder.pathname) sups->finder.callback = & stap_uprobe_process_found;";
782040b3 4637 s.op->newline() << "else if (sups->pathname) sups->finder.mmap_callback = & stap_uprobe_mmap_found;";
6d0f3f0c 4638 s.op->newline() << "rc = stap_register_task_finder_target (& sups->finder);";
5e112f92
FCE
4639
4640 // NB: if (rc), there is no need (XXX: nor any way) to clean up any
4641 // finders already registered, since mere registration does not
4642 // cause any utrace or memory allocation actions. That happens only
4643 // later, once the task finder engine starts running. So, for a
4644 // partial initialization requiring unwind, we need do nothing.
4645 s.op->newline() << "if (rc) break;";
4646
888af770
FCE
4647 s.op->newline(-1) << "}";
4648}
4649
4650
4651void
4652uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
4653{
4654 if (probes.empty()) return;
4655 s.op->newline() << "/* ---- user probes ---- */";
4656
6d0f3f0c
FCE
4657 // NB: there is no stap_unregister_task_finder_target call;
4658 // important stuff like utrace cleanups are done by
d41d451c
FCE
4659 // __stp_task_finder_cleanup() via stap_stop_task_finder().
4660 //
4661 // This function blocks until all callbacks are completed, so there
4662 // is supposed to be no possibility of any registration-related code starting
4663 // to run in parallel with our shutdown here. So we don't need to protect the
4664 // stap_uprobes[] array with the mutex.
5e112f92 4665
01b05e2e 4666 s.op->newline() << "for (j=0; j<MAXUPROBES; j++) {";
5e112f92
FCE
4667 s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[j];";
4668 s.op->newline() << "struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
6d0f3f0c 4669 s.op->newline() << "if (sup->spec_index < 0) continue;"; // free slot
3568f1dd
FCE
4670
4671 s.op->newline() << "if (sups->return_p) {";
4672 s.op->newline(1) << "#ifdef DEBUG_UPROBES";
d41d451c 4673 s.op->newline() << "printk (KERN_INFO \"-uretprobe spec %d index %d pid %d addr %p\\n\", sup->spec_index, j, sup->up.pid, (void*) sup->up.vaddr);";
3568f1dd 4674 s.op->newline() << "#endif";
80b4ad8b
FCE
4675 // NB: PR6829 does not change that we still need to unregister at
4676 // *this* time -- when the script as a whole exits.
3568f1dd
FCE
4677 s.op->newline() << "unregister_uretprobe (& sup->urp);";
4678 s.op->newline(-1) << "} else {";
4679 s.op->newline(1) << "#ifdef DEBUG_UPROBES";
d41d451c 4680 s.op->newline() << "printk (KERN_INFO \"-uprobe spec %d index %d pid %d addr %p\\n\", sup->spec_index, j, sup->urp.u.pid, (void*) sup->urp.u.vaddr);";
3568f1dd
FCE
4681 s.op->newline() << "#endif";
4682 s.op->newline() << "unregister_uprobe (& sup->up);";
4683 s.op->newline(-1) << "}";
4684
6d0f3f0c 4685 s.op->newline() << "sup->spec_index = -1;";
3568f1dd
FCE
4686
4687 // XXX: uprobe missed counts?
4688
6d0f3f0c 4689 s.op->newline(-1) << "}";
5e112f92
FCE
4690
4691 s.op->newline() << "mutex_destroy (& stap_uprobes_lock);";
888af770
FCE
4692}
4693
e6fe60e7
AM
4694// ------------------------------------------------------------------------
4695// Kprobe derived probes
4696// ------------------------------------------------------------------------
4697
4627ed58 4698static const string TOK_KPROBE("kprobe");
e6fe60e7 4699
bae55db9
JS
4700struct kprobe_derived_probe: public derived_probe
4701{
4702 kprobe_derived_probe (probe *base,
4703 probe_point *location,
4704 const string& name,
4705 int64_t stmt_addr,
4706 bool has_return,
4707 bool has_statement,
4708 bool has_maxactive,
4709 long maxactive_val
4710 );
4711 string symbol_name;
4712 Dwarf_Addr addr;
4713 bool has_return;
4714 bool has_statement;
4715 bool has_maxactive;
4716 long maxactive_val;
4717 bool access_var;
4718 void printsig (std::ostream &o) const;
4719 void join_group (systemtap_session& s);
4720};
4721
4722struct kprobe_derived_probe_group: public derived_probe_group
4723{
4724private:
4725 multimap<string,kprobe_derived_probe*> probes_by_module;
4726 typedef multimap<string,kprobe_derived_probe*>::iterator p_b_m_iterator;
4727
4728public:
4729 void enroll (kprobe_derived_probe* probe);
4730 void emit_module_decls (systemtap_session& s);
4731 void emit_module_init (systemtap_session& s);
4732 void emit_module_exit (systemtap_session& s);
4733};
4734
e6fe60e7
AM
4735kprobe_derived_probe::kprobe_derived_probe (probe *base,
4736 probe_point *location,
b6371390 4737 const string& name,
e6fe60e7 4738 int64_t stmt_addr,
b6371390
JS
4739 bool has_return,
4740 bool has_statement,
4741 bool has_maxactive,
4742 long maxactive_val
4743 ):
e6fe60e7
AM
4744 derived_probe (base, location),
4745 symbol_name (name), addr (stmt_addr),
b6371390
JS
4746 has_return (has_return), has_statement (has_statement),
4747 has_maxactive (has_maxactive), maxactive_val (maxactive_val)
e6fe60e7
AM
4748{
4749 this->tok = base->tok;
4750 this->access_var = false;
4751
4752#ifndef USHRT_MAX
4753#define USHRT_MAX 32767
4754#endif
4755
46856d8d
JS
4756 // Expansion of $target variables in the probe body produces an error during
4757 // translate phase, since we're not using debuginfo
4758
e6fe60e7 4759 vector<probe_point::component*> comps;
46856d8d 4760 comps.push_back (new probe_point::component(TOK_KPROBE));
e6fe60e7 4761
46856d8d
JS
4762 if (has_statement)
4763 {
4764 comps.push_back (new probe_point::component(TOK_STATEMENT, new literal_number(addr)));
4765 comps.push_back (new probe_point::component(TOK_ABSOLUTE));
4766 }
4767 else
4768 {
4769 size_t pos = name.find(':');
4770 if (pos != string::npos)
4771 {
4772 string module = name.substr(0, pos);
4773 string function = name.substr(pos + 1);
4774 comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module)));
4775 comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(function)));
4776 }
4777 else
4778 comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(name)));
46856d8d 4779 }
888af770 4780
b6371390
JS
4781 if (has_return)
4782 comps.push_back (new probe_point::component(TOK_RETURN));
4783 if (has_maxactive)
4784 comps.push_back (new probe_point::component(TOK_MAXACTIVE, new literal_number(maxactive_val)));
4785
e6fe60e7
AM
4786 this->sole_location()->components = comps;
4787}
888af770 4788
e6fe60e7
AM
4789void kprobe_derived_probe::printsig (ostream& o) const
4790{
4791 sole_location()->print (o);
4792 o << " /* " << " name = " << symbol_name << "*/";
4793 printsig_nested (o);
4794}
4795
4796void kprobe_derived_probe::join_group (systemtap_session& s)
4797{
4798
4799 if (! s.kprobe_derived_probes)
4800 s.kprobe_derived_probes = new kprobe_derived_probe_group ();
4801 s.kprobe_derived_probes->enroll (this);
4802
4803}
4804
4805void kprobe_derived_probe_group::enroll (kprobe_derived_probe* p)
4806{
4807 probes_by_module.insert (make_pair (p->symbol_name, p));
4808 // probes of same symbol should share single kprobe/kretprobe
4809}
4810
4811void
4812kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
4813{
4814 if (probes_by_module.empty()) return;
4815
4816 s.op->newline() << "/* ---- kprobe-based probes ---- */";
4817
4818 // Warn of misconfigured kernels
4819 s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
4820 s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
4821 s.op->newline() << "#endif";
4822 s.op->newline();
4823
f07c3b68
FCE
4824 s.op->newline() << "#ifndef KRETACTIVE";
4825 s.op->newline() << "#define KRETACTIVE (max(15,6*NR_CPUS))";
4826 s.op->newline() << "#endif";
4827
e6fe60e7 4828 // Forward declare the master entry functions
88747011 4829 s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
e6fe60e7 4830 s.op->line() << " struct pt_regs *regs);";
88747011 4831 s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
e6fe60e7
AM
4832 s.op->line() << " struct pt_regs *regs);";
4833
4834 // Emit an array of kprobe/kretprobe pointers
4835 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
c9116e99 4836 s.op->newline() << "static void * stap_unreg_kprobes2[" << probes_by_module.size() << "];";
e6fe60e7
AM
4837 s.op->newline() << "#endif";
4838
4839 // Emit the actual probe list.
4840
4841 s.op->newline() << "static struct stap_dwarfless_kprobe {";
4842 s.op->newline(1) << "union { struct kprobe kp; struct kretprobe krp; } u;";
4843 s.op->newline() << "#ifdef __ia64__";
4844 s.op->newline() << "struct kprobe dummy;";
4845 s.op->newline() << "#endif";
4846 s.op->newline(-1) << "} stap_dwarfless_kprobes[" << probes_by_module.size() << "];";
4847 // NB: bss!
4848
4849 s.op->newline() << "static struct stap_dwarfless_probe {";
4850 s.op->newline(1) << "const unsigned return_p:1;";
4851 s.op->newline() << "const unsigned maxactive_p:1;";
b350f56b 4852 s.op->newline() << "const unsigned optional_p:1;";
e6fe60e7
AM
4853 s.op->newline() << "unsigned registered_p:1;";
4854 s.op->newline() << "const unsigned short maxactive_val;";
4855
4856 // Function Names are mostly small and uniform enough to justify putting
4857 // char[MAX]'s into the array instead of relocated char*'s.
4858
4859 size_t pp_name_max = 0, symbol_string_name_max = 0;
4860 size_t pp_name_tot = 0, symbol_string_name_tot = 0;
4861 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
4862 {
4863 kprobe_derived_probe* p = it->second;
4864#define DOIT(var,expr) do { \
4865 size_t var##_size = (expr) + 1; \
4866 var##_max = max (var##_max, var##_size); \
4867 var##_tot += var##_size; } while (0)
4868 DOIT(pp_name, lex_cast_qstring(*p->sole_location()).size());
4869 DOIT(symbol_string_name, p->symbol_name.size());
4870#undef DOIT
4871 }
4872
4873#define CALCIT(var) \
4874 s.op->newline() << "const char " << #var << "[" << var##_name_max << "] ;";
4875
4876 CALCIT(pp);
4877 CALCIT(symbol_string);
4878#undef CALCIT
4879
4880 s.op->newline() << "const unsigned long address;";
4881 s.op->newline() << "void (* const ph) (struct context*);";
4882 s.op->newline(-1) << "} stap_dwarfless_probes[] = {";
4883 s.op->indent(1);
4884
4885 for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
4886 {
4887 kprobe_derived_probe* p = it->second;
4888 s.op->newline() << "{";
4889 if (p->has_return)
4890 s.op->line() << " .return_p=1,";
4891
4892 if (p->has_maxactive)
4893 {
4894 s.op->line() << " .maxactive_p=1,";
4895 assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
4896 s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
4897 }
c8d9d15e 4898
b350f56b
JS
4899 if (p->locations[0]->optional)
4900 s.op->line() << " .optional_p=1,";
4901
e6fe60e7 4902 if (p->has_statement)
c8d9d15e 4903 s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
e6fe60e7 4904 else
c8d9d15e 4905 s.op->line() << " .symbol_string=\"" << p->symbol_name << "\",";
e6fe60e7
AM
4906
4907 s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
4908 s.op->line() << " .ph=&" << p->name;
4909 s.op->line() << " },";
4910 }
4911
4912 s.op->newline(-1) << "};";
4913
4914 // Emit the kprobes callback function
4915 s.op->newline();
88747011 4916 s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
e6fe60e7
AM
4917 s.op->line() << " struct pt_regs *regs) {";
4918 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
4919 s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);";
4920 // Check that the index is plausible
4921 s.op->newline() << "struct stap_dwarfless_probe *sdp = &stap_dwarfless_probes[";
4922 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
4923 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4924 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4925 s.op->line() << "];";
4926 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp");
4927 s.op->newline() << "c->regs = regs;";
6415ddde
MW
4928
4929 // Make it look like the IP is set as it wouldn't have been replaced
4930 // by a breakpoint instruction when calling real probe handler. Reset
4931 // IP regs on return, so we don't confuse kprobes. PR10458
4932 s.op->newline() << "{";
4933 s.op->indent(1);
4934 s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
4935 s.op->newline() << "REG_IP(regs) = (unsigned long) inst->addr;";
e6fe60e7 4936 s.op->newline() << "(*sdp->ph) (c);";
6415ddde
MW
4937 s.op->newline() << "REG_IP(regs) = kprobes_ip;";
4938 s.op->newline(-1) << "}";
4939
e6fe60e7
AM
4940 common_probe_entryfn_epilogue (s.op);
4941 s.op->newline() << "return 0;";
4942 s.op->newline(-1) << "}";
4943
4944 // Same for kretprobes
4945 s.op->newline();
88747011 4946 s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
e6fe60e7
AM
4947 s.op->line() << " struct pt_regs *regs) {";
4948 s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
4949
4950 // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
4951 s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);";
4952 // Check that the index is plausible
4953 s.op->newline() << "struct stap_dwarfless_probe *sdp = &stap_dwarfless_probes[";
4954 s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
4955 s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4956 // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4957 s.op->line() << "];";
4958
4959 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", "sdp->pp");
4960 s.op->newline() << "c->regs = regs;";
4961 s.op->newline() << "c->pi = inst;"; // for assisting runtime's backtrace logic
6415ddde
MW
4962
4963 // Make it look like the IP is set as it wouldn't have been replaced
4964 // by a breakpoint instruction when calling real probe handler. Reset
4965 // IP regs on return, so we don't confuse kprobes. PR10458
4966 s.op->newline() << "{";
4967 s.op->indent(1);
4968 s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
4969 s.op->newline() << "REG_IP(regs) = (unsigned long) inst->rp->kp.addr;";
e6fe60e7 4970 s.op->newline() << "(*sdp->ph) (c);";
6415ddde
MW
4971 s.op->newline() << "REG_IP(regs) = kprobes_ip;";
4972 s.op->newline(-1) << "}";
4973
e6fe60e7
AM
4974 common_probe_entryfn_epilogue (s.op);
4975 s.op->newline() << "return 0;";
4976 s.op->newline(-1) << "}";
4977}
4978
4979
4980void
4981kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
4982{
e6fe60e7 4983 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
c8d9d15e 4984 s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
e6fe60e7 4985 s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
c8d9d15e
JS
4986 s.op->newline() << "void *addr = (void *) sdp->address;";
4987 s.op->newline() << "const char *symbol_name = addr ? NULL : sdp->symbol_string;";
e6fe60e7
AM
4988 s.op->newline() << "probe_point = sdp->pp;"; // for error messages
4989 s.op->newline() << "if (sdp->return_p) {";
c8d9d15e 4990 s.op->newline(1) << "kp->u.krp.kp.addr = addr;";
9f38e653 4991 s.op->newline() << "kp->u.krp.kp.symbol_name = (char *) symbol_name;";
e6fe60e7
AM
4992 s.op->newline() << "if (sdp->maxactive_p) {";
4993 s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
4994 s.op->newline(-1) << "} else {";
f07c3b68 4995 s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;";
e6fe60e7 4996 s.op->newline(-1) << "}";
88747011 4997 s.op->newline() << "kp->u.krp.handler = &enter_kretprobe2_probe;";
e6fe60e7
AM
4998 // to ensure safeness of bspcache, always use aggr_kprobe on ia64
4999 s.op->newline() << "#ifdef __ia64__";
e6fe60e7 5000 s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;";
c8d9d15e
JS
5001 s.op->newline() << "kp->dummy.symbol_name = kp->u.krp.kp.symbol_name;";
5002 s.op->newline() << "kp->dummy.pre_handler = NULL;";
e6fe60e7
AM
5003 s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5004 s.op->newline() << "if (rc == 0) {";
5005 s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);";
5006 s.op->newline() << "if (rc != 0)";
5007 s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5008 s.op->newline(-2) << "}";
5009 s.op->newline() << "#else";
5010 s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
5011 s.op->newline() << "#endif";
5012 s.op->newline(-1) << "} else {";
5013 // to ensure safeness of bspcache, always use aggr_kprobe on ia64
c8d9d15e 5014 s.op->newline(1) << "kp->u.kp.addr = addr;";
9f38e653 5015 s.op->newline() << "kp->u.kp.symbol_name = (char *) symbol_name;";
88747011 5016 s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe2_probe;";
e6fe60e7 5017 s.op->newline() << "#ifdef __ia64__";
e6fe60e7 5018 s.op->newline() << "kp->dummy.pre_handler = NULL;";
c8d9d15e
JS
5019 s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
5020 s.op->newline() << "kp->dummy.symbol_name = kp->u.kp.symbol_name;";
e6fe60e7
AM
5021 s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5022 s.op->newline() << "if (rc == 0) {";
5023 s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);";
5024 s.op->newline() << "if (rc != 0)";
5025 s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5026 s.op->newline(-2) << "}";
5027 s.op->newline() << "#else";
5028 s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
5029 s.op->newline() << "#endif";
5030 s.op->newline(-1) << "}";
5031 s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
5032 s.op->newline(1) << "sdp->registered_p = 0;";
b350f56b 5033 s.op->newline() << "if (!sdp->optional_p)";
4a4edc21 5034 s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, addr, rc);";
b350f56b 5035 s.op->newline(-1) << "rc = 0;"; // continue with other probes
e6fe60e7
AM
5036 // XXX: shall we increment numskipped?
5037 s.op->newline(-1) << "}";
5038
5039 s.op->newline() << "else sdp->registered_p = 1;";
5040 s.op->newline(-1) << "}"; // for loop
e6fe60e7
AM
5041}
5042
5043void
5044kprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
5045{
5046 //Unregister kprobes by batch interfaces.
5047 s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
5048 s.op->newline() << "j = 0;";
5049 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5050 s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
5051 s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
5052 s.op->newline() << "if (! sdp->registered_p) continue;";
5053 s.op->newline() << "if (!sdp->return_p)";
c9116e99 5054 s.op->newline(1) << "stap_unreg_kprobes2[j++] = &kp->u.kp;";
e6fe60e7 5055 s.op->newline(-2) << "}";
c9116e99 5056 s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes2, j);";
e6fe60e7
AM
5057 s.op->newline() << "j = 0;";
5058 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5059 s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
5060 s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
5061 s.op->newline() << "if (! sdp->registered_p) continue;";
5062 s.op->newline() << "if (sdp->return_p)";
c9116e99 5063 s.op->newline(1) << "stap_unreg_kprobes2[j++] = &kp->u.krp;";
e6fe60e7 5064 s.op->newline(-2) << "}";
c9116e99 5065 s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes2, j);";
e6fe60e7
AM
5066 s.op->newline() << "#ifdef __ia64__";
5067 s.op->newline() << "j = 0;";
5068 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5069 s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
5070 s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
5071 s.op->newline() << "if (! sdp->registered_p) continue;";
c9116e99 5072 s.op->newline() << "stap_unreg_kprobes2[j++] = &kp->dummy;";
e6fe60e7 5073 s.op->newline(-1) << "}";
c9116e99 5074 s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes2, j);";
e6fe60e7
AM
5075 s.op->newline() << "#endif";
5076 s.op->newline() << "#endif";
5077
5078 s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5079 s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
5080 s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
5081 s.op->newline() << "if (! sdp->registered_p) continue;";
5082 s.op->newline() << "if (sdp->return_p) {";
5083 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
5084 s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
5085 s.op->newline() << "#endif";
5086 s.op->newline() << "atomic_add (kp->u.krp.nmissed, & skipped_count);";
5087 s.op->newline() << "#ifdef STP_TIMING";
5088 s.op->newline() << "if (kp->u.krp.nmissed)";
5089 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->pp, kp->u.krp.nmissed);";
5090 s.op->newline(-1) << "#endif";
5091 s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
5092 s.op->newline() << "#ifdef STP_TIMING";
5093 s.op->newline() << "if (kp->u.krp.kp.nmissed)";
5094 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %d\\n\", sdp->pp, kp->u.krp.kp.nmissed);";
5095 s.op->newline(-1) << "#endif";
5096 s.op->newline(-1) << "} else {";
5097 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
5098 s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
5099 s.op->newline() << "#endif";
5100 s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
5101 s.op->newline() << "#ifdef STP_TIMING";
5102 s.op->newline() << "if (kp->u.kp.nmissed)";
5103 s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %d\\n\", sdp->pp, kp->u.kp.nmissed);";
5104 s.op->newline(-1) << "#endif";
5105 s.op->newline(-1) << "}";
5106 s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
5107 s.op->newline() << "unregister_kprobe (&kp->dummy);";
5108 s.op->newline() << "#endif";
5109 s.op->newline() << "sdp->registered_p = 0;";
5110 s.op->newline(-1) << "}";
5111}
5112
5113struct kprobe_builder: public derived_probe_builder
5114{
5115 kprobe_builder() {}
5116 virtual void build(systemtap_session & sess,
5117 probe * base,
5118 probe_point * location,
5119 literal_map_t const & parameters,
5120 vector<derived_probe *> & finished_results);
5121};
5122
5123
5124void
5125kprobe_builder::build(systemtap_session & sess,
5126 probe * base,
5127 probe_point * location,
5128 literal_map_t const & parameters,
5129 vector<derived_probe *> & finished_results)
5130{
5131 string function_string_val, module_string_val;
b6371390
JS
5132 int64_t statement_num_val = 0, maxactive_val = 0;
5133 bool has_function_str, has_module_str, has_statement_num;
5134 bool has_absolute, has_return, has_maxactive;
e6fe60e7 5135
b6371390
JS
5136 has_function_str = get_param(parameters, TOK_FUNCTION, function_string_val);
5137 has_module_str = get_param(parameters, TOK_MODULE, module_string_val);
5138 has_return = has_null_param (parameters, TOK_RETURN);
5139 has_maxactive = get_param(parameters, TOK_MAXACTIVE, maxactive_val);
5140 has_statement_num = get_param(parameters, TOK_STATEMENT, statement_num_val);
5141 has_absolute = has_null_param (parameters, TOK_ABSOLUTE);
e6fe60e7 5142
b6371390
JS
5143 if (has_function_str)
5144 {
5145 if (has_module_str)
5146 function_string_val = module_string_val + ":" + function_string_val;
5147
5148 finished_results.push_back (new kprobe_derived_probe (base,
5149 location, function_string_val,
5150 0, has_return,
5151 has_statement_num,
5152 has_maxactive,
5153 maxactive_val));
5154 }
e6fe60e7 5155 else
b6371390
JS
5156 {
5157 // assert guru mode for absolute probes
5158 if ( has_statement_num && has_absolute && !base->privileged )
5159 throw semantic_error ("absolute statement probe in unprivileged script", base->tok);
5160
5161 finished_results.push_back (new kprobe_derived_probe (base,
5162 location, "",
5163 statement_num_val,
5164 has_return,
5165 has_statement_num,
5166 has_maxactive,
5167 maxactive_val));
5168 }
e6fe60e7 5169}
b6371390
JS
5170
5171
342d3f96 5172
0a6f5a3f
JS
5173// ------------------------------------------------------------------------
5174// statically inserted kernel-tracepoint derived probes
5175// ------------------------------------------------------------------------
5176
6fb70fb7
JS
5177struct tracepoint_arg
5178{
ad370dcc 5179 string name, c_type, typecast;
dcaa1a65 5180 bool usable, used, isptr;
f8a968bc 5181 Dwarf_Die type_die;
dcaa1a65 5182 tracepoint_arg(): usable(false), used(false), isptr(false) {}
6fb70fb7 5183};
0a6f5a3f
JS
5184
5185struct tracepoint_derived_probe: public derived_probe
5186{
79189b84
JS
5187 tracepoint_derived_probe (systemtap_session& s,
5188 dwflpp& dw, Dwarf_Die& func_die,
5189 const string& tracepoint_name,
5190 probe* base_probe, probe_point* location);
5191
5192 systemtap_session& sess;
6fb70fb7
JS
5193 string tracepoint_name, header;
5194 vector <struct tracepoint_arg> args;
79189b84 5195
6fb70fb7 5196 void build_args(dwflpp& dw, Dwarf_Die& func_die);
e2086848 5197 void printargs (std::ostream &o) const;
79189b84 5198 void join_group (systemtap_session& s);
3e3bd7b6 5199 void print_dupe_stamp(ostream& o);
f8a968bc 5200 void emit_probe_context_vars (translator_output* o);
0a6f5a3f
JS
5201};
5202
5203
5204struct tracepoint_derived_probe_group: public generic_dpg<tracepoint_derived_probe>
5205{
79189b84
JS
5206 void emit_module_decls (systemtap_session& s);
5207 void emit_module_init (systemtap_session& s);
5208 void emit_module_exit (systemtap_session& s);
0a6f5a3f
JS
5209};
5210
5211
f8a968bc
JS
5212struct tracepoint_var_expanding_visitor: public var_expanding_visitor
5213{
5214 tracepoint_var_expanding_visitor(dwflpp& dw, const string& probe_name,
5215 vector <struct tracepoint_arg>& args):
5216 dw (dw), probe_name (probe_name), args (args) {}
5217 dwflpp& dw;
5218 const string& probe_name;
5219 vector <struct tracepoint_arg>& args;
5220
5221 void visit_target_symbol (target_symbol* e);
5222 void visit_target_symbol_arg (target_symbol* e);
5223 void visit_target_symbol_context (target_symbol* e);
5224};
5225
5226
5227void
5228tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
5229{
5230 string argname = e->base_name.substr(1);
5231
5232 // search for a tracepoint parameter matching this name
5233 tracepoint_arg *arg = NULL;
5234 for (unsigned i = 0; i < args.size(); ++i)
dcaa1a65 5235 if (args[i].usable && args[i].name == argname)
f8a968bc
JS
5236 {
5237 arg = &args[i];
5238 arg->used = true;
5239 break;
5240 }
5241
5242 if (arg == NULL)
5243 {
5244 stringstream alternatives;
5245 for (unsigned i = 0; i < args.size(); ++i)
5246 alternatives << " $" << args[i].name;
046e7190 5247 alternatives << " $$name $$parms $$vars";
f8a968bc
JS
5248
5249 // We hope that this value ends up not being referenced after all, so it
5250 // can be optimized out quietly.
5251 semantic_error* saveme =
5252 new semantic_error("unable to find tracepoint variable '" + e->base_name
5253 + "' (alternatives:" + alternatives.str () + ")", e->tok);
5254 // NB: we can have multiple errors, since a target variable
5255 // may be expanded in several different contexts:
5256 // trace ("*") { $foo->bar }
5257 saveme->chain = e->saved_conversion_error;
5258 e->saved_conversion_error = saveme;
5259 provide (e);
5260 return;
5261 }
5262
5263 // make sure we're not dereferencing base types
5264 if (!e->components.empty() && !arg->isptr)
c67847a0 5265 switch (e->components[0].type)
f8a968bc
JS
5266 {
5267 case target_symbol::comp_literal_array_index:
5268 throw semantic_error("tracepoint variable '" + e->base_name
5269 + "' may not be used as array", e->tok);
5270 case target_symbol::comp_struct_member:
5271 throw semantic_error("tracepoint variable '" + e->base_name
5272 + "' may not be used as a structure", e->tok);
5273 default:
5274 throw semantic_error("invalid use of tracepoint variable '"
5275 + e->base_name + "'", e->tok);
5276 }
5277
5278 // we can only write to dereferenced fields, and only if guru mode is on
5279 bool lvalue = is_active_lvalue(e);
5280 if (lvalue && (!dw.sess.guru_mode || e->components.empty()))
5281 throw semantic_error("write to tracepoint variable '" + e->base_name
5282 + "' not permitted", e->tok);
ad370dcc
JS
5283 // XXX: if a struct/union arg is passed by value, then writing to its fields
5284 // is also meaningless until you dereference past a pointer member. It's
5285 // harder to detect and prevent that though...
f8a968bc
JS
5286
5287 if (e->components.empty())
5288 {
03c75a4a
JS
5289 if (e->addressof)
5290 throw semantic_error("cannot take address of tracepoint variable", e->tok);
5291
3e3bd7b6
JS
5292 // Just grab the value from the probe locals
5293 e->probe_context_var = "__tracepoint_arg_" + arg->name;
5294 e->type = pe_long;
5295 provide (e);
f8a968bc
JS
5296 }
5297 else
5298 {
5299 // Synthesize a function to dereference the dwarf fields,
5300 // with a pointer parameter that is the base tracepoint variable
5301 functiondecl *fdecl = new functiondecl;
5302 fdecl->tok = e->tok;
5303 embeddedcode *ec = new embeddedcode;
5304 ec->tok = e->tok;
5305
5306 string fname = (string(lvalue ? "_tracepoint_tvar_set" : "_tracepoint_tvar_get")
5307 + "_" + e->base_name.substr(1)
5308 + "_" + lex_cast<string>(tick++));
5309
5310 fdecl->name = fname;
5311 fdecl->body = ec;
5312
5313 try
5314 {
b4c34c26 5315 ec->code = dw.literal_stmt_for_pointer (&arg->type_die, e,
f8a968bc
JS
5316 lvalue, fdecl->type);
5317 }
5318 catch (const semantic_error& er)
5319 {
5320 // We suppress this error message, and pass the unresolved
5321 // variable to the next pass. We hope that this value ends
5322 // up not being referenced after all, so it can be optimized out
5323 // quietly.
5324 semantic_error* saveme = new semantic_error (er); // copy it
f8a968bc
JS
5325 // NB: we can have multiple errors, since a target variable
5326 // may be expanded in several different contexts:
5327 // trace ("*") { $foo->bar }
5328 saveme->chain = e->saved_conversion_error;
5329 e->saved_conversion_error = saveme;
5330 provide (e);
5331 return;
5332 }
5333
5334 // Give the fdecl an argument for the raw tracepoint value
5335 vardecl *v1 = new vardecl;
5336 v1->type = pe_long;
5337 v1->name = "pointer";
5338 v1->tok = e->tok;
5339 fdecl->formal_args.push_back(v1);
5340
5341 if (lvalue)
5342 {
5343 // Modify the fdecl so it carries a pe_long formal
5344 // argument called "value".
5345
5346 // FIXME: For the time being we only support setting target
5347 // variables which have base types; these are 'pe_long' in
5348 // stap's type vocabulary. Strings and pointers might be
5349 // reasonable, some day, but not today.
5350
5351 vardecl *v2 = new vardecl;
5352 v2->type = pe_long;
5353 v2->name = "value";
5354 v2->tok = e->tok;
5355 fdecl->formal_args.push_back(v2);
5356 }
5357 else
5358 ec->code += "/* pure */";
5359
5360 dw.sess.functions[fdecl->name] = fdecl;
5361
5362 // Synthesize a functioncall.
5363 functioncall* n = new functioncall;
5364 n->tok = e->tok;
5365 n->function = fname;
5366 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
5367
5368 // make the original a bare target symbol for the tracepoint value,
5369 // which will be passed into the dwarf dereferencing code
5370 e->components.clear();
5371 n->args.push_back(require(e));
5372
5373 if (lvalue)
5374 {
5375 // Provide the functioncall to our parent, so that it can be
5376 // used to substitute for the assignment node immediately above
5377 // us.
5378 assert(!target_symbol_setter_functioncalls.empty());
5379 *(target_symbol_setter_functioncalls.top()) = n;
5380 }
5381
5382 provide (n);
5383 }
5384}
5385
5386
5387void
5388tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
5389{
03c75a4a
JS
5390 if (e->addressof)
5391 throw semantic_error("cannot take address of context variable", e->tok);
5392
f8a968bc
JS
5393 if (is_active_lvalue (e))
5394 throw semantic_error("write to tracepoint '" + e->base_name + "' not permitted", e->tok);
5395
5396 if (!e->components.empty())
c67847a0 5397 switch (e->components[0].type)
f8a968bc
JS
5398 {
5399 case target_symbol::comp_literal_array_index:
5400 throw semantic_error("tracepoint '" + e->base_name + "' may not be used as array",
5401 e->tok);
5402 case target_symbol::comp_struct_member:
5403 throw semantic_error("tracepoint '" + e->base_name + "' may not be used as a structure",
5404 e->tok);
5405 default:
5406 throw semantic_error("invalid tracepoint '" + e->base_name + "' use", e->tok);
5407 }
5408
5409 if (e->base_name == "$$name")
5410 {
5411 // Synthesize a functioncall.
5412 functioncall* n = new functioncall;
5413 n->tok = e->tok;
5414 n->function = "_mark_name_get";
5415 n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
5416 provide (n);
5417 }
046e7190 5418 else if (e->base_name == "$$vars" || e->base_name == "$$parms")
f8a968bc 5419 {
f8a968bc
JS
5420 print_format* pf = new print_format;
5421
5422 // Convert $$vars to sprintf of a list of vars which we recursively evaluate
5423 // NB: we synthesize a new token here rather than reusing
5424 // e->tok, because print_format::print likes to use
5425 // its tok->content.
5426 token* pf_tok = new token(*e->tok);
5427 pf_tok->content = "sprintf";
5428
5429 pf->tok = pf_tok;
5430 pf->print_to_stream = false;
5431 pf->print_with_format = true;
5432 pf->print_with_delim = false;
5433 pf->print_with_newline = false;
5434 pf->print_char = false;
5435
5436 for (unsigned i = 0; i < args.size(); ++i)
5437 {
dcaa1a65
JS
5438 if (!args[i].usable)
5439 continue;
f8a968bc
JS
5440 if (i > 0)
5441 pf->raw_components += " ";
5442 pf->raw_components += args[i].name;
3e3bd7b6 5443 target_symbol *tsym = new target_symbol;
f8a968bc
JS
5444 tsym->tok = e->tok;
5445 tsym->base_name = "$" + args[i].name;
5446
5447 // every variable should always be accessible!
5448 tsym->saved_conversion_error = 0;
5449 expression *texp = require (tsym); // NB: throws nothing ...
5450 assert (!tsym->saved_conversion_error); // ... but this is how we know it happened.
5451
d0ad1746 5452 pf->raw_components += args[i].isptr ? "=%p" : "=%#x";
f8a968bc
JS
5453 pf->args.push_back(texp);
5454 }
5455
5456 pf->components = print_format::string_to_components(pf->raw_components);
5457 provide (pf);
5458 }
5459 else
5460 assert(0); // shouldn't get here
5461}
5462
5463void
5464tracepoint_var_expanding_visitor::visit_target_symbol (target_symbol* e)
5465{
5466 assert(e->base_name.size() > 0 && e->base_name[0] == '$');
5467
046e7190
JS
5468 if (e->base_name == "$$name" ||
5469 e->base_name == "$$parms" ||
5470 e->base_name == "$$vars")
f8a968bc
JS
5471 visit_target_symbol_context (e);
5472 else
5473 visit_target_symbol_arg (e);
5474}
5475
5476
5477
79189b84
JS
5478tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s,
5479 dwflpp& dw, Dwarf_Die& func_die,
5480 const string& tracepoint_name,
5481 probe* base, probe_point* loc):
5482 derived_probe (base, new probe_point(*loc) /* .components soon rewritten */),
5483 sess (s), tracepoint_name (tracepoint_name)
5484{
5485 // create synthetic probe point name; preserve condition
5486 vector<probe_point::component*> comps;
5487 comps.push_back (new probe_point::component (TOK_KERNEL));
5488 comps.push_back (new probe_point::component (TOK_TRACE, new literal_string (tracepoint_name)));
5489 this->sole_location()->components = comps;
5490
6fb70fb7
JS
5491 // fill out the available arguments in this tracepoint
5492 build_args(dw, func_die);
5493
5494 // determine which header defined this tracepoint
5495 string decl_file = dwarf_decl_file(&func_die);
5496 size_t header_pos = decl_file.rfind("trace/");
5497 if (header_pos == string::npos)
5498 throw semantic_error ("cannot parse header location for tracepoint '"
5499 + tracepoint_name + "' in '"
5500 + decl_file + "'");
5501 header = decl_file.substr(header_pos);
5502
5503 // tracepoints from FOO_event_types.h should really be included from FOO.h
5504 // XXX can dwarf tell us the include hierarchy? it would be better to
5505 // ... walk up to see which one was directly included by tracequery.c
3c1b3d06 5506 // XXX: see also PR9993.
6fb70fb7
JS
5507 header_pos = header.find("_event_types");
5508 if (header_pos != string::npos)
5509 header.erase(header_pos, 12);
5510
f8a968bc
JS
5511 // Now expand the local variables in the probe body
5512 tracepoint_var_expanding_visitor v (dw, name, args);
5513 this->body = v.require (this->body);
5514
79189b84
JS
5515 if (sess.verbose > 2)
5516 clog << "tracepoint-based " << name << " tracepoint='" << tracepoint_name
5517 << "'" << endl;
5518}
5519
5520
6fb70fb7
JS
5521static bool
5522dwarf_type_name(Dwarf_Die& type_die, string& c_type)
5523{
219e62c7
JS
5524 // if we've gotten down to a basic type, then we're done
5525 bool done = true;
5526 switch (dwarf_tag(&type_die))
6fb70fb7 5527 {
219e62c7
JS
5528 case DW_TAG_structure_type:
5529 c_type.append("struct ");
5530 break;
5531 case DW_TAG_union_type:
5532 c_type.append("union ");
5533 break;
5534 case DW_TAG_typedef:
5535 case DW_TAG_base_type:
5536 break;
5537 default:
5538 done = false;
5539 break;
5540 }
5541 if (done)
5542 {
5543 c_type.append(dwarf_diename_integrate(&type_die));
6fb70fb7
JS
5544 return true;
5545 }
5546
5547 // otherwise, this die is a type modifier.
5548
5549 // recurse into the referent type
219e62c7 5550 // if it can't be named, just call it "void"
6fb70fb7
JS
5551 Dwarf_Attribute subtype_attr;
5552 Dwarf_Die subtype_die;
5553 if (!dwarf_attr_integrate(&type_die, DW_AT_type, &subtype_attr)
5554 || !dwarf_formref_die(&subtype_attr, &subtype_die)
5555 || !dwarf_type_name(subtype_die, c_type))
219e62c7 5556 c_type = "void";
6fb70fb7
JS
5557
5558 const char *suffix = NULL;
5559 switch (dwarf_tag(&type_die))
5560 {
5561 case DW_TAG_pointer_type:
5562 suffix = "*";
5563 break;
5564 case DW_TAG_array_type:
5565 suffix = "[]";
5566 break;
5567 case DW_TAG_const_type:
5568 suffix = " const";
5569 break;
5570 case DW_TAG_volatile_type:
5571 suffix = " volatile";
5572 break;
5573 default:
5574 return false;
5575 }
5576 c_type.append(suffix);
219e62c7
JS
5577
5578 // XXX HACK! The va_list isn't usable as found in the debuginfo...
5579 if (c_type == "struct __va_list_tag*")
5580 c_type = "va_list";
5581
6fb70fb7
JS
5582 return true;
5583}
5584
5585
f8a968bc 5586static bool
dcaa1a65 5587resolve_tracepoint_arg_type(tracepoint_arg& arg)
f8a968bc
JS
5588{
5589 Dwarf_Attribute type_attr;
dcaa1a65 5590 switch (dwarf_tag(&arg.type_die))
f8a968bc
JS
5591 {
5592 case DW_TAG_typedef:
5593 case DW_TAG_const_type:
5594 case DW_TAG_volatile_type:
5595 // iterate on the referent type
dcaa1a65
JS
5596 return (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr)
5597 && dwarf_formref_die(&type_attr, &arg.type_die)
5598 && resolve_tracepoint_arg_type(arg));
f8a968bc
JS
5599 case DW_TAG_base_type:
5600 // base types will simply be treated as script longs
dcaa1a65 5601 arg.isptr = false;
f8a968bc
JS
5602 return true;
5603 case DW_TAG_pointer_type:
dcaa1a65
JS
5604 // pointers can be treated as script longs,
5605 // and if we know their type, they can also be dereferenced
5606 if (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr)
5607 && dwarf_formref_die(&type_attr, &arg.type_die))
5608 arg.isptr = true;
ad370dcc
JS
5609 arg.typecast = "(intptr_t)";
5610 return true;
5611 case DW_TAG_structure_type:
5612 case DW_TAG_union_type:
5613 // for structs/unions which are passed by value, we turn it into
5614 // a pointer that can be dereferenced.
5615 arg.isptr = true;
5616 arg.typecast = "(intptr_t)&";
dcaa1a65 5617 return true;
f8a968bc
JS
5618 default:
5619 // should we consider other types too?
5620 return false;
5621 }
5622}
5623
5624
6fb70fb7
JS
5625void
5626tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die)
5627{
5628 Dwarf_Die arg;
5629 if (dwarf_child(&func_die, &arg) == 0)
5630 do
5631 if (dwarf_tag(&arg) == DW_TAG_formal_parameter)
5632 {
5633 // build a tracepoint_arg for this parameter
5634 tracepoint_arg tparg;
5635 tparg.name = dwarf_diename_integrate(&arg);
5636
5637 // read the type of this parameter
5638 Dwarf_Attribute type_attr;
6fb70fb7 5639 if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr)
f8a968bc 5640 || !dwarf_formref_die (&type_attr, &tparg.type_die)
dcaa1a65 5641 || !dwarf_type_name(tparg.type_die, tparg.c_type))
6fb70fb7
JS
5642 throw semantic_error ("cannot get type of tracepoint '"
5643 + tracepoint_name + "' parameter '"
5644 + tparg.name + "'");
5645
dcaa1a65 5646 tparg.usable = resolve_tracepoint_arg_type(tparg);
6fb70fb7
JS
5647 args.push_back(tparg);
5648 if (sess.verbose > 4)
5649 clog << "found parameter for tracepoint '" << tracepoint_name
5650 << "': type:'" << tparg.c_type
5651 << "' name:'" << tparg.name << "'" << endl;
5652 }
5653 while (dwarf_siblingof(&arg, &arg) == 0);
5654}
5655
e2086848
WH
5656void
5657tracepoint_derived_probe::printargs(std::ostream &o) const
5658{
dcaa1a65
JS
5659 for (unsigned i = 0; i < args.size(); ++i)
5660 if (args[i].usable)
5661 o << " $" << args[i].name << ":" << args[i].c_type;
e2086848 5662}
6fb70fb7 5663
79189b84
JS
5664void
5665tracepoint_derived_probe::join_group (systemtap_session& s)
5666{
5667 if (! s.tracepoint_derived_probes)
5668 s.tracepoint_derived_probes = new tracepoint_derived_probe_group ();
5669 s.tracepoint_derived_probes->enroll (this);
5670}
5671
5672
3e3bd7b6
JS
5673void
5674tracepoint_derived_probe::print_dupe_stamp(ostream& o)
5675{
5676 for (unsigned i = 0; i < args.size(); i++)
5677 if (args[i].used)
5678 o << "__tracepoint_arg_" << args[i].name << endl;
5679}
5680
5681
f8a968bc
JS
5682void
5683tracepoint_derived_probe::emit_probe_context_vars (translator_output* o)
5684{
5685 for (unsigned i = 0; i < args.size(); i++)
5686 if (args[i].used)
5687 o->newline() << "int64_t __tracepoint_arg_" << args[i].name << ";";
5688}
5689
5690
3c1b3d06
FCE
5691static vector<string> tracepoint_extra_headers ()
5692{
5693 vector<string> they_live;
5694 // PR 9993
5695 // XXX: may need this to be configurable
5696 they_live.push_back ("linux/skbuff.h");
5697 return they_live;
5698}
5699
5700
79189b84
JS
5701void
5702tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s)
5703{
5704 if (probes.empty())
5705 return;
5706
96b030fe
JS
5707 s.op->newline() << "/* ---- tracepoint probes ---- */";
5708 s.op->newline();
79189b84 5709
3c1b3d06
FCE
5710 // PR9993: Add extra headers to work around undeclared types in individual
5711 // include/trace/foo.h files
5712 const vector<string>& extra_headers = tracepoint_extra_headers ();
5713 for (unsigned z=0; z<extra_headers.size(); z++)
5714 s.op->newline() << "#include <" << extra_headers[z] << ">\n";
5715
6fb70fb7
JS
5716 for (unsigned i = 0; i < probes.size(); ++i)
5717 {
5718 tracepoint_derived_probe *p = probes[i];
96b030fe
JS
5719
5720 // emit a separate entry function for each probe, since tracepoints
5721 // don't provide any sort of context pointer.
6fb70fb7
JS
5722 s.op->newline() << "#include <" << p->header << ">";
5723 s.op->newline() << "static void enter_tracepoint_probe_" << i << "(";
8df306c4
JS
5724 if (p->args.size() == 0)
5725 s.op->line() << "void";
6fb70fb7
JS
5726 for (unsigned j = 0; j < p->args.size(); ++j)
5727 {
5728 if (j > 0)
5729 s.op->line() << ", ";
5730 s.op->line() << p->args[j].c_type << " __tracepoint_arg_" << p->args[j].name;
5731 }
5732 s.op->line() << ") {";
5733 s.op->indent(1);
ad002306 5734 common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING",
c12d974f 5735 lex_cast_qstring (*p->sole_location()));
f8a968bc 5736 s.op->newline() << "c->marker_name = "
c12d974f
FCE
5737 << lex_cast_qstring (p->tracepoint_name)
5738 << ";";
f8a968bc
JS
5739 for (unsigned j = 0; j < p->args.size(); ++j)
5740 if (p->args[j].used)
5741 {
5742 s.op->newline() << "c->locals[0]." << p->name << ".__tracepoint_arg_"
5743 << p->args[j].name << " = (int64_t)";
ad370dcc 5744 s.op->line() << p->args[j].typecast;
f8a968bc
JS
5745 s.op->line() << "__tracepoint_arg_" << p->args[j].name << ";";
5746 }
6fb70fb7
JS
5747 s.op->newline() << p->name << " (c);";
5748 common_probe_entryfn_epilogue (s.op);
5749 s.op->newline(-1) << "}";
96b030fe
JS
5750
5751 // emit normalized registration functions
5752 s.op->newline() << "static int register_tracepoint_probe_" << i << "(void) {";
5753 s.op->newline(1) << "return register_trace_" << p->tracepoint_name
5754 << "(enter_tracepoint_probe_" << i << ");";
5755 s.op->newline(-1) << "}";
86758d5f
JS
5756
5757 // NB: we're not prepared to deal with unreg failures. However, failures
5758 // can only occur if the tracepoint doesn't exist (yet?), or if we
5759 // weren't even registered. The former should be OKed by the initial
5760 // registration call, and the latter is safe to ignore.
5761 s.op->newline() << "static void unregister_tracepoint_probe_" << i << "(void) {";
5762 s.op->newline(1) << "(void) unregister_trace_" << p->tracepoint_name
96b030fe
JS
5763 << "(enter_tracepoint_probe_" << i << ");";
5764 s.op->newline(-1) << "}";
6fb70fb7
JS
5765 s.op->newline();
5766 }
96b030fe
JS
5767
5768 // emit an array of registration functions for easy init/shutdown
5769 s.op->newline() << "static struct stap_tracepoint_probe {";
5770 s.op->newline(1) << "int (*reg)(void);";
86758d5f 5771 s.op->newline(0) << "void (*unreg)(void);";
96b030fe
JS
5772 s.op->newline(-1) << "} stap_tracepoint_probes[] = {";
5773 s.op->indent(1);
5774 for (unsigned i = 0; i < probes.size(); ++i)
5775 {
5776 s.op->newline () << "{";
5777 s.op->line() << " .reg=&register_tracepoint_probe_" << i << ",";
5778 s.op->line() << " .unreg=&unregister_tracepoint_probe_" << i;
5779 s.op->line() << " },";
5780 }
5781 s.op->newline(-1) << "};";
5782 s.op->newline();
79189b84
JS
5783}
5784
5785
5786void
5787tracepoint_derived_probe_group::emit_module_init (systemtap_session &s)
5788{
5789 if (probes.size () == 0)
5790 return;
5791
5792 s.op->newline() << "/* init tracepoint probes */";
96b030fe
JS
5793 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
5794 s.op->newline(1) << "rc = stap_tracepoint_probes[i].reg();";
5795 s.op->newline() << "if (rc) {";
5796 s.op->newline(1) << "for (j=i-1; j>=0; j--)"; // partial rollback
5797 s.op->newline(1) << "stap_tracepoint_probes[j].unreg();";
5798 s.op->newline(-1) << "break;"; // don't attempt to register any more probes
5799 s.op->newline(-1) << "}";
5800 s.op->newline(-1) << "}";
bc9a523d
FCE
5801
5802 // This would be technically proper (on those autoconf-detectable
5803 // kernels that include this function in tracepoint.h), however we
5804 // already make several calls to synchronze_sched() during our
5805 // shutdown processes.
5806
5807 // s.op->newline() << "if (rc)";
5808 // s.op->newline(1) << "tracepoint_synchronize_unregister();";
5809 // s.op->indent(-1);
79189b84
JS
5810}
5811
5812
5813void
5814tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s)
5815{
5816 if (probes.empty())
5817 return;
5818
96b030fe
JS
5819 s.op->newline() << "/* deregister tracepoint probes */";
5820 s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
5821 s.op->newline(1) << "stap_tracepoint_probes[i].unreg();";
5822 s.op->indent(-1);
bc9a523d
FCE
5823
5824 // Not necessary: see above.
5825
5826 // s.op->newline() << "tracepoint_synchronize_unregister();";
79189b84
JS
5827}
5828
5829
75ead1f7
JS
5830struct tracepoint_query : public base_query
5831{
5832 tracepoint_query(dwflpp & dw, const string & tracepoint,
5833 probe * base_probe, probe_point * base_loc,
5834 vector<derived_probe *> & results):
5835 base_query(dw, "*"), tracepoint(tracepoint),
5836 base_probe(base_probe), base_loc(base_loc),
5837 results(results) {}
5838
5839 const string& tracepoint;
5840
5841 probe * base_probe;
5842 probe_point * base_loc;
5843 vector<derived_probe *> & results;
f982c59b 5844 set<string> probed_names;
75ead1f7
JS
5845
5846 void handle_query_module();
5847 int handle_query_cu(Dwarf_Die * cudie);
5848 int handle_query_func(Dwarf_Die * func);
5849
5850 static int tracepoint_query_cu (Dwarf_Die * cudie, void * arg);
5851 static int tracepoint_query_func (Dwarf_Die * func, base_query * query);
5852};
5853
5854
5855void
5856tracepoint_query::handle_query_module()
5857{
5858 // look for the tracepoints in each CU
5859 dw.iterate_over_cus(tracepoint_query_cu, this);
5860}
5861
5862
5863int
5864tracepoint_query::handle_query_cu(Dwarf_Die * cudie)
5865{
5866 dw.focus_on_cu (cudie);
5867
5868 // look at each function to see if it's a tracepoint
5869 string function = "stapprobe_" + tracepoint;
5870 return dw.iterate_over_functions (tracepoint_query_func, this, function);
5871}
5872
5873
5874int
5875tracepoint_query::handle_query_func(Dwarf_Die * func)
5876{
5877 dw.focus_on_function (func);
5878
5879 assert(dw.function_name.compare(0, 10, "stapprobe_") == 0);
5880 string tracepoint_instance = dw.function_name.substr(10);
f982c59b
JS
5881
5882 // check for duplicates -- sometimes tracepoint headers may be indirectly
5883 // included in more than one of our tracequery modules.
5884 if (!probed_names.insert(tracepoint_instance).second)
5885 return DWARF_CB_OK;
5886
79189b84
JS
5887 derived_probe *dp = new tracepoint_derived_probe (dw.sess, dw, *func,
5888 tracepoint_instance,
5889 base_probe, base_loc);
5890 results.push_back (dp);
75ead1f7
JS
5891 return DWARF_CB_OK;
5892}
5893
5894
5895int
5896tracepoint_query::tracepoint_query_cu (Dwarf_Die * cudie, void * arg)
5897{
5898 tracepoint_query * q = static_cast<tracepoint_query *>(arg);
5899 if (pending_interrupts) return DWARF_CB_ABORT;
5900 return q->handle_query_cu(cudie);
5901}
5902
5903
5904int
5905tracepoint_query::tracepoint_query_func (Dwarf_Die * func, base_query * query)
5906{
5907 tracepoint_query * q = static_cast<tracepoint_query *>(query);
5908 if (pending_interrupts) return DWARF_CB_ABORT;
5909 return q->handle_query_func(func);
5910}
5911
5912
0a6f5a3f
JS
5913struct tracepoint_builder: public derived_probe_builder
5914{
5915private:
5916 dwflpp *dw;
5917 bool init_dw(systemtap_session& s);
f982c59b 5918 string get_tracequery_module(systemtap_session& s, const string& header);
0a6f5a3f
JS
5919
5920public:
3c1b3d06 5921
0a6f5a3f
JS
5922 tracepoint_builder(): dw(0) {}
5923 ~tracepoint_builder() { delete dw; }
5924
5925 void build_no_more (systemtap_session& s)
5926 {
5927 if (dw && s.verbose > 3)
5928 clog << "tracepoint_builder releasing dwflpp" << endl;
5929 delete dw;
5930 dw = NULL;
5931 }
5932
5933 void build(systemtap_session& s,
5934 probe *base, probe_point *location,
5935 literal_map_t const& parameters,
5936 vector<derived_probe*>& finished_results);
5937};
5938
5939
f982c59b
JS
5940string
5941tracepoint_builder::get_tracequery_module(systemtap_session& s,
5942 const string& header)
0a6f5a3f 5943{
a2639cb7 5944 string tracequery_path;
b278033a
JS
5945 if (s.use_cache)
5946 {
5947 // see if the cached module exists
f982c59b 5948 tracequery_path = find_tracequery_hash(s, header);
a2639cb7 5949 if (!tracequery_path.empty())
b278033a 5950 {
a2639cb7 5951 int fd = open(tracequery_path.c_str(), O_RDONLY);
b278033a
JS
5952 if (fd != -1)
5953 {
5954 if (s.verbose > 2)
a2639cb7 5955 clog << "Pass 2: using cached " << tracequery_path << endl;
b278033a 5956 close(fd);
f982c59b 5957 return tracequery_path;
b278033a
JS
5958 }
5959 }
5960 }
5961
5962 // no cached module, time to make it
f982c59b
JS
5963
5964 size_t root_pos = header.rfind("/include/");
5965 string short_header = (root_pos != string::npos) ?
5966 header.substr(root_pos + 9) : header;
5967
0a6f5a3f 5968 string tracequery_ko;
f982c59b
JS
5969 int rc = make_tracequery(s, tracequery_ko, short_header,
5970 tracepoint_extra_headers());
0a6f5a3f 5971 if (rc != 0)
f982c59b 5972 return "";
0a6f5a3f 5973
b278033a
JS
5974 if (s.use_cache)
5975 {
5976 // try to save tracequery in the cache
5977 if (s.verbose > 2)
5978 clog << "Copying " << tracequery_ko
a2639cb7 5979 << " to " << tracequery_path << endl;
b278033a 5980 if (copy_file(tracequery_ko.c_str(),
a2639cb7 5981 tracequery_path.c_str()) != 0)
b278033a 5982 cerr << "Copy failed (\"" << tracequery_ko << "\" to \""
a2639cb7 5983 << tracequery_path << "\"): " << strerror(errno) << endl;
b278033a 5984 }
f982c59b
JS
5985 return tracequery_ko;
5986}
5987
5988
5989bool
5990tracepoint_builder::init_dw(systemtap_session& s)
5991{
5992 if (dw != NULL)
5993 return true;
5994
5995 vector<string> tracequery_modules;
5996
5997 glob_t trace_glob;
5998 string globs[] = {
5999 "/include/trace/*.h",
6000 "/include/trace/events/*.h",
6001 "/source/include/trace/*.h",
6002 "/source/include/trace/events/*.h",
6003 };
6004 for (unsigned z = 0; z < sizeof(globs) / sizeof(globs[0]); z++)
6005 {
6006 string glob_str(s.kernel_build_tree + globs[z]);
6007 glob(glob_str.c_str(), 0, NULL, &trace_glob);
6008 for (unsigned i = 0; i < trace_glob.gl_pathc; ++i)
6009 {
6010 string header(trace_glob.gl_pathv[i]);
6011
6012 // filter out a few known "internal-only" headers
6013 if (header.find("/ftrace.h") != string::npos)
6014 continue;
6015 if (header.find("/trace_events.h") != string::npos)
6016 continue;
6017 if (header.find("_event_types.h") != string::npos)
6018 continue;
6019
6020 string tracequery_path = get_tracequery_module(s, header);
6021 if (!tracequery_path.empty())
6022 tracequery_modules.push_back(tracequery_path);
6023 }
6024 globfree(&trace_glob);
6025 }
6026
6027 // TODO: consider other sources of tracepoint headers too, like from
6028 // a command-line parameter or some environment or .systemtaprc
0a6f5a3f 6029
f982c59b 6030 dw = new dwflpp(s, tracequery_modules);
0a6f5a3f
JS
6031 return true;
6032}
6033
6034
6035void
6036tracepoint_builder::build(systemtap_session& s,
6037 probe *base, probe_point *location,
6038 literal_map_t const& parameters,
6039 vector<derived_probe*>& finished_results)
6040{
6041 if (!init_dw(s))
6042 return;
6043
75ead1f7
JS
6044 string tracepoint;
6045 assert(get_param (parameters, TOK_TRACE, tracepoint));
6046
6047 tracepoint_query q(*dw, tracepoint, base, location, finished_results);
51178501 6048 dw->iterate_over_modules(&query_module, &q);
0a6f5a3f
JS
6049}
6050
6051
6052
b55bc428 6053// ------------------------------------------------------------------------
bd2b1e68 6054// Standard tapset registry.
b55bc428
FCE
6055// ------------------------------------------------------------------------
6056
7a053d3b 6057void
f8220a7b 6058register_standard_tapsets(systemtap_session & s)
b55bc428 6059{
47e0478e 6060 register_tapset_been(s);
93646f4d 6061 register_tapset_itrace(s);
dd0e4fa7 6062 register_tapset_mark(s);
01c2eefe 6063 register_tapset_perfmon(s);
7a212aa8 6064 register_tapset_procfs(s);
912e8c59 6065 register_tapset_timers(s);
b84779a5 6066 register_tapset_utrace(s);
912e8c59 6067
b98a8d73 6068
7a24d422 6069 // dwarf-based kprobe/uprobe parts
c4ce66a1 6070 dwarf_derived_probe::register_patterns(s);
30a279be 6071
888af770
FCE
6072 // XXX: user-space starter set
6073 s.pattern_root->bind_num(TOK_PROCESS)
6074 ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
6075 ->bind(new uprobe_builder ());
6076 s.pattern_root->bind_num(TOK_PROCESS)
6077 ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN)
6078 ->bind(new uprobe_builder ());
6079
0a6f5a3f
JS
6080 // kernel tracepoint probes
6081 s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_TRACE)
6082 ->bind(new tracepoint_builder());
6083
e6fe60e7
AM
6084 // Kprobe based probe
6085 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)
6086 ->bind(new kprobe_builder());
6087 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
6088 ->bind_str(TOK_FUNCTION)->bind(new kprobe_builder());
6089 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
6090 ->bind(new kprobe_builder());
b6371390
JS
6091 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
6092 ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder());
e6fe60e7
AM
6093 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
6094 ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)->bind(new kprobe_builder());
b6371390
JS
6095 s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
6096 ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
6097 ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder());
e6fe60e7
AM
6098 s.pattern_root->bind(TOK_KPROBE)->bind_num(TOK_STATEMENT)
6099 ->bind(TOK_ABSOLUTE)->bind(new kprobe_builder());
b55bc428 6100}
dc38c0ae
DS
6101
6102
b20febf3
FCE
6103vector<derived_probe_group*>
6104all_session_groups(systemtap_session& s)
dc38c0ae 6105{
b20febf3 6106 vector<derived_probe_group*> g;
912e8c59
JS
6107
6108#define DOONE(x) \
6109 if (s. x##_derived_probes) \
6110 g.push_back ((derived_probe_group*)(s. x##_derived_probes))
ab655cf8
DS
6111
6112 // Note that order *is* important here. We want to make sure we
6113 // register (actually run) begin probes before any other probe type
6114 // is run. Similarly, when unregistering probes, we want to
6115 // unregister (actually run) end probes after every other probe type
6116 // has be unregistered. To do the latter,
6117 // c_unparser::emit_module_exit() will run this list backwards.
b20febf3
FCE
6118 DOONE(be);
6119 DOONE(dwarf);
888af770 6120 DOONE(uprobe);
b20febf3
FCE
6121 DOONE(timer);
6122 DOONE(profile);
6123 DOONE(mark);
0a6f5a3f 6124 DOONE(tracepoint);
e6fe60e7 6125 DOONE(kprobe);
b20febf3
FCE
6126 DOONE(hrtimer);
6127 DOONE(perfmon);
ce82316f 6128 DOONE(procfs);
935447c8
DS
6129
6130 // Another "order is important" item. We want to make sure we
6131 // "register" the dummy task_finder probe group after all probe
6132 // groups that use the task_finder.
6133 DOONE(utrace);
a96d1db0 6134 DOONE(itrace);
935447c8 6135 DOONE(task_finder);
b20febf3
FCE
6136#undef DOONE
6137 return g;
46b84a80 6138}
73267b89
JS
6139
6140/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 1.514543 seconds and 5 git commands to generate.