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