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