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