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