Branch data Line data Source code
1 : : // tapset resolution
2 : : // Copyright (C) 2005-2013 Red Hat Inc.
3 : : // Copyright (C) 2005-2007 Intel Corporation.
4 : : // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
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"
14 : : #include "tapsets.h"
15 : : #include "task_finder.h"
16 : : #include "tapset-dynprobe.h"
17 : : #include "translate.h"
18 : : #include "session.h"
19 : : #include "util.h"
20 : : #include "buildrun.h"
21 : : #include "dwarf_wrappers.h"
22 : : #include "auto_free.h"
23 : : #include "hash.h"
24 : : #include "dwflpp.h"
25 : : #include "setupdwfl.h"
26 : : #include <gelf.h>
27 : :
28 : : #include "sdt_types.h"
29 : :
30 : : #include <cstdlib>
31 : : #include <algorithm>
32 : : #include <deque>
33 : : #include <iostream>
34 : : #include <fstream>
35 : : #include <map>
36 : : #include <set>
37 : : #include <sstream>
38 : : #include <stdexcept>
39 : : #include <vector>
40 : : #include <cstdarg>
41 : : #include <cassert>
42 : : #include <iomanip>
43 : : #include <cerrno>
44 : :
45 : : extern "C" {
46 : : #include <fcntl.h>
47 : : #include <elfutils/libdwfl.h>
48 : : #include <elfutils/libdw.h>
49 : : #include <dwarf.h>
50 : : #include <elf.h>
51 : : #include <obstack.h>
52 : : #include <glob.h>
53 : : #include <fnmatch.h>
54 : : #include <stdio.h>
55 : : #include <sys/types.h>
56 : : #include <sys/stat.h>
57 : : #include <math.h>
58 : : #include <regex.h>
59 : : #include <unistd.h>
60 : : #include <wordexp.h>
61 : :
62 : : #define __STDC_FORMAT_MACROS
63 : : #include <inttypes.h>
64 : : }
65 : :
66 : :
67 : : using namespace std;
68 : : using namespace __gnu_cxx;
69 : :
70 : :
71 : :
72 : : // ------------------------------------------------------------------------
73 : :
74 : : string
75 : 16766 : common_probe_init (derived_probe* p)
76 : : {
77 [ - + ]: 16766 : assert(p->session_index != (unsigned)-1);
78 [ + - ][ + - ]: 16766 : return "(&stap_probes[" + lex_cast(p->session_index) + "])";
[ + - ]
79 : : }
80 : :
81 : :
82 : : void
83 : 1937 : common_probe_entryfn_prologue (systemtap_session& s,
84 : : string statestr, string probe,
85 : : string probe_type, bool overload_processing)
86 : : {
87 [ - + ]: 1937 : if (s.runtime_usermode_p())
88 : 0 : s.op->newline() << "int _stp_saved_errno = errno;";
89 : 1937 : s.op->newline() << "#ifdef STP_ALIBI";
90 : 1937 : s.op->newline() << "atomic_inc(probe_alibi(" << probe << "->index));";
91 : 1937 : s.op->newline() << "#else";
92 : :
93 : 1937 : s.op->newline() << "struct context* __restrict__ c;";
94 : 1937 : s.op->newline() << "#if !INTERRUPTIBLE";
95 : 1937 : s.op->newline() << "unsigned long flags;";
96 : 1937 : s.op->newline() << "#endif";
97 : :
98 : 1937 : s.op->newline() << "#ifdef STP_TIMING";
99 : 1937 : s.op->newline() << "Stat stat = probe_timing(" << probe << "->index);";
100 : 1937 : s.op->newline() << "#endif";
101 [ + + ][ + - ]: 1937 : if (overload_processing && !s.runtime_usermode_p())
[ + + ]
102 : 1448 : s.op->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
103 : : else
104 : 489 : s.op->newline() << "#ifdef STP_TIMING";
105 : :
106 [ + - ]: 1937 : if (! s.runtime_usermode_p())
107 : 1937 : s.op->newline() << "cycles_t cycles_atstart = get_cycles ();";
108 : : else
109 : : {
110 : 0 : s.op->newline() << "struct timespec timespec_atstart;";
111 : 0 : s.op->newline() << "(void)clock_gettime(CLOCK_MONOTONIC_RAW, ×pec_atstart);";
112 : : }
113 : 1937 : s.op->newline() << "#endif";
114 : :
115 : 1937 : s.op->newline() << "#if INTERRUPTIBLE";
116 : 1937 : s.op->newline() << "preempt_disable ();";
117 : 1937 : s.op->newline() << "#else";
118 : 1937 : s.op->newline() << "local_irq_save (flags);";
119 : 1937 : s.op->newline() << "#endif";
120 : :
121 [ + - ]: 1937 : if (! s.runtime_usermode_p())
122 : : {
123 : : // Check for enough free enough stack space
124 : 1937 : s.op->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space
125 : 1937 : s.op->newline(1) << "< (MINSTACKSPACE + sizeof (struct thread_info)))) {"; // needed space
126 : : // XXX: may need porting to platforms where task_struct is not
127 : : // at bottom of kernel stack NB: see also
128 : : // CONFIG_DEBUG_STACKOVERFLOW
129 : 1937 : s.op->newline() << "atomic_inc (skipped_count());";
130 : 1937 : s.op->newline() << "#ifdef STP_TIMING";
131 : 1937 : s.op->newline() << "atomic_inc (skipped_count_lowstack());";
132 : 1937 : s.op->newline() << "#endif";
133 : 1937 : s.op->newline() << "goto probe_epilogue;";
134 : 1937 : s.op->newline(-1) << "}";
135 : : }
136 : :
137 : 1937 : s.op->newline() << "if (atomic_read (session_state()) != " << statestr << ")";
138 : 1937 : s.op->newline(1) << "goto probe_epilogue;";
139 : 1937 : s.op->indent(-1);
140 : :
141 : 1937 : s.op->newline() << "c = _stp_runtime_entryfn_get_context();";
142 [ - + ]: 1937 : if (s.runtime_usermode_p())
143 : : {
144 : 0 : s.op->newline() << "if (!c) {";
145 : 0 : s.op->newline(1) << "#if !INTERRUPTIBLE";
146 : 0 : s.op->newline() << "atomic_inc (skipped_count());";
147 : 0 : s.op->newline() << "#endif";
148 : 0 : s.op->newline() << "#ifdef STP_TIMING";
149 : 0 : s.op->newline() << "atomic_inc (skipped_count_reentrant());";
150 : 0 : s.op->newline() << "#ifdef DEBUG_REENTRANCY";
151 : 0 : s.op->newline() << "_stp_warn (\"Skipped %s\\n\", " << probe << "->pp);";
152 : 0 : s.op->newline() << "#endif";
153 : 0 : s.op->newline() << "#endif";
154 : 0 : s.op->newline() << "goto probe_epilogue;";
155 : 0 : s.op->newline(-1) << "}";
156 : : }
157 : :
158 : 1937 : s.op->newline() << "if (atomic_inc_return (& c->busy) != 1) {";
159 : 1937 : s.op->newline(1) << "#if !INTERRUPTIBLE";
160 : 1937 : s.op->newline() << "atomic_inc (skipped_count());";
161 : 1937 : s.op->newline() << "#endif";
162 : 1937 : s.op->newline() << "#ifdef STP_TIMING";
163 : 1937 : s.op->newline() << "atomic_inc (skipped_count_reentrant());";
164 : 1937 : s.op->newline() << "#ifdef DEBUG_REENTRANCY";
165 : 1937 : s.op->newline() << "_stp_warn (\"Skipped %s due to %s residency on cpu %u\\n\", "
166 : 1937 : << probe << "->pp, c->probe_point ?: \"?\", smp_processor_id());";
167 : : // NB: There is a conceivable race condition here with reading
168 : : // c->probe_point, knowing that this other probe is sort of running.
169 : : // However, in reality, it's interrupted. Plus even if it were able
170 : : // to somehow start again, and stop before we read c->probe_point,
171 : : // at least we have that ?: "?" bit in there to avoid a NULL deref.
172 : 1937 : s.op->newline() << "#endif";
173 : 1937 : s.op->newline() << "#endif";
174 : 1937 : s.op->newline() << "atomic_dec (& c->busy);";
175 : 1937 : s.op->newline() << "goto probe_epilogue;";
176 : 1937 : s.op->newline(-1) << "}";
177 : 1937 : s.op->newline();
178 : 1937 : s.op->newline() << "c->last_stmt = 0;";
179 : 1937 : s.op->newline() << "c->last_error = 0;";
180 : 1937 : s.op->newline() << "c->nesting = -1;"; // NB: PR10516 packs locals[] tighter
181 : 1937 : s.op->newline() << "c->uregs = 0;";
182 : 1937 : s.op->newline() << "c->kregs = 0;";
183 : 1937 : s.op->newline() << "#if defined __ia64__";
184 : 1937 : s.op->newline() << "c->unwaddr = 0;";
185 : 1937 : s.op->newline() << "#endif";
186 [ - + ]: 1937 : if (s.runtime_usermode_p())
187 : 0 : s.op->newline() << "c->probe_index = " << probe << "->index;";
188 : 1937 : s.op->newline() << "c->probe_point = " << probe << "->pp;";
189 : 1937 : s.op->newline() << "#ifdef STP_NEED_PROBE_NAME";
190 : 1937 : s.op->newline() << "c->probe_name = " << probe << "->pn;";
191 : 1937 : s.op->newline() << "#endif";
192 : 1937 : s.op->newline() << "c->probe_type = " << probe_type << ";";
193 : : // reset Individual Probe State union
194 : 1937 : s.op->newline() << "memset(&c->ips, 0, sizeof(c->ips));";
195 : 1937 : s.op->newline() << "c->user_mode_p = 0; c->full_uregs_p = 0;";
196 : 1937 : s.op->newline() << "#ifdef STAP_NEED_REGPARM"; // i386 or x86_64 register.stp
197 : 1937 : s.op->newline() << "c->regparm = 0;";
198 : 1937 : s.op->newline() << "#endif";
199 : :
200 [ + + ]: 1937 : if(!s.suppress_time_limits){
201 : 1936 : s.op->newline() << "#if INTERRUPTIBLE";
202 : 1936 : s.op->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;";
203 : 1936 : s.op->newline() << "#else";
204 : 1936 : s.op->newline() << "c->actionremaining = MAXACTION;";
205 : 1936 : s.op->newline() << "#endif";
206 : : }
207 : : // NB: The following would actually be incorrect.
208 : : // That's because cycles_sum/cycles_base values are supposed to survive
209 : : // between consecutive probes. Periodically (STP_OVERLOAD_INTERVAL
210 : : // cycles), the values will be reset.
211 : : /*
212 : : s.op->newline() << "#ifdef STP_OVERLOAD";
213 : : s.op->newline() << "c->cycles_sum = 0;";
214 : : s.op->newline() << "c->cycles_base = 0;";
215 : : s.op->newline() << "#endif";
216 : : */
217 : :
218 : 1937 : s.op->newline() << "#if defined(STP_NEED_UNWIND_DATA)";
219 : 1937 : s.op->newline() << "c->uwcache_user.state = uwcache_uninitialized;";
220 : 1937 : s.op->newline() << "c->uwcache_kernel.state = uwcache_uninitialized;";
221 : 1937 : s.op->newline() << "#endif";
222 : 1937 : }
223 : :
224 : :
225 : : void
226 : 1937 : common_probe_entryfn_epilogue (systemtap_session& s,
227 : : bool overload_processing)
228 : : {
229 [ + + ][ + - ]: 1937 : if (overload_processing && !s.runtime_usermode_p())
[ + + ]
230 : 1448 : s.op->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
231 : : else
232 : 489 : s.op->newline() << "#ifdef STP_TIMING";
233 : 1937 : s.op->newline() << "{";
234 : 1937 : s.op->indent(1);
235 [ + - ]: 1937 : if (! s.runtime_usermode_p())
236 : : {
237 : 1937 : s.op->newline() << "cycles_t cycles_atend = get_cycles ();";
238 : : // NB: we truncate cycles counts to 32 bits. Perhaps it should be
239 : : // fewer, if the hardware counter rolls over really quickly. We
240 : : // handle 32-bit wraparound here.
241 : 1937 : s.op->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
242 : 1937 : s.op->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
243 : 1937 : s.op->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
244 : 1937 : s.op->indent(-1);
245 : : }
246 : : else
247 : : {
248 : 0 : s.op->newline() << "struct timespec timespec_atend, timespec_elapsed;";
249 : 0 : s.op->newline() << "long cycles_elapsed;";
250 : 0 : s.op->newline() << "(void)clock_gettime(CLOCK_MONOTONIC_RAW, ×pec_atend);";
251 : 0 : s.op->newline() << "_stp_timespec_sub(×pec_atend, ×pec_atstart, ×pec_elapsed);";
252 : : // 'cycles_elapsed' is really elapsed nanoseconds
253 : 0 : s.op->newline() << "cycles_elapsed = (timespec_elapsed.tv_sec * NSEC_PER_SEC) + timespec_elapsed.tv_nsec;";
254 : : }
255 : :
256 : 1937 : s.op->newline() << "#ifdef STP_TIMING";
257 : 1937 : s.op->newline() << "if (likely (stat)) _stp_stat_add(stat, cycles_elapsed);";
258 : 1937 : s.op->newline() << "#endif";
259 : :
260 [ + + ][ + - ]: 1937 : if (overload_processing && !s.runtime_usermode_p())
[ + + ]
261 : : {
262 : 1448 : s.op->newline() << "#ifdef STP_OVERLOAD";
263 : 1448 : s.op->newline() << "{";
264 : : // If the cycle count has wrapped (cycles_atend > cycles_base),
265 : : // let's go ahead and pretend the interval has been reached.
266 : : // This should reset cycles_base and cycles_sum.
267 : 1448 : s.op->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)";
268 : 1448 : s.op->newline(1) << "? (cycles_atend - c->cycles_base)";
269 : 1448 : s.op->newline() << ": (STP_OVERLOAD_INTERVAL + 1);";
270 : 1448 : s.op->newline(-1) << "c->cycles_sum += cycles_elapsed;";
271 : :
272 : : // If we've spent more than STP_OVERLOAD_THRESHOLD cycles in a
273 : : // probe during the last STP_OVERLOAD_INTERVAL cycles, the probe
274 : : // has overloaded the system and we need to quit.
275 : : // NB: this is not suppressible via --suppress-runtime-errors,
276 : : // because this is a system safety metric that we cannot trust
277 : : // unprivileged users to override.
278 : 1448 : s.op->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {";
279 : 1448 : s.op->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {";
280 : 1448 : s.op->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");";
281 : 1448 : s.op->newline() << "atomic_set (session_state(), STAP_SESSION_ERROR);";
282 : 1448 : s.op->newline() << "atomic_inc (error_count());";
283 : 1448 : s.op->newline(-1) << "}";
284 : :
285 : 1448 : s.op->newline() << "c->cycles_base = cycles_atend;";
286 : 1448 : s.op->newline() << "c->cycles_sum = 0;";
287 : 1448 : s.op->newline(-1) << "}";
288 : 1448 : s.op->newline(-1) << "}";
289 : 1448 : s.op->newline() << "#endif";
290 : : }
291 : :
292 : 1937 : s.op->newline(-1) << "}";
293 : 1937 : s.op->newline() << "#endif";
294 : :
295 : 1937 : s.op->newline() << "c->probe_point = 0;"; // vacated
296 : 1937 : s.op->newline() << "#ifdef STP_NEED_PROBE_NAME";
297 : 1937 : s.op->newline() << "c->probe_name = 0;";
298 : 1937 : s.op->newline() << "#endif";
299 : 1937 : s.op->newline() << "c->probe_type = 0;";
300 : :
301 : :
302 : 1937 : s.op->newline() << "if (unlikely (c->last_error && c->last_error[0])) {";
303 : 1937 : s.op->indent(1);
304 [ + + ]: 1937 : if (s.suppress_handler_errors) // PR 13306
305 : : {
306 : 6 : s.op->newline() << "atomic_inc (error_count());";
307 : : }
308 : : else
309 : : {
310 : 1931 : s.op->newline() << "if (c->last_stmt != NULL)";
311 : 1931 : s.op->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);";
312 : 1931 : s.op->newline(-1) << "else";
313 : 1931 : s.op->newline(1) << "_stp_softerror (\"%s\", c->last_error);";
314 : 1931 : s.op->indent(-1);
315 : 1931 : s.op->newline() << "atomic_inc (error_count());";
316 : 1931 : s.op->newline() << "if (atomic_read (error_count()) > MAXERRORS) {";
317 : 1931 : s.op->newline(1) << "atomic_set (session_state(), STAP_SESSION_ERROR);";
318 : 1931 : s.op->newline() << "_stp_exit ();";
319 : 1931 : s.op->newline(-1) << "}";
320 : : }
321 : :
322 : 1937 : s.op->newline(-1) << "}";
323 : :
324 : :
325 : 1937 : s.op->newline() << "atomic_dec (&c->busy);";
326 : :
327 : 1937 : s.op->newline(-1) << "probe_epilogue:"; // context is free
328 : 1937 : s.op->indent(1);
329 : :
330 : 1937 : s.op->newline() << "_stp_runtime_entryfn_put_context();";
331 [ + + ]: 1937 : if (! s.suppress_handler_errors) // PR 13306
332 : : {
333 : : // Check for excessive skip counts.
334 : 1931 : s.op->newline() << "if (unlikely (atomic_read (skipped_count()) > MAXSKIPPED)) {";
335 : 1931 : s.op->newline(1) << "if (unlikely (pseudo_atomic_cmpxchg(session_state(), STAP_SESSION_RUNNING, STAP_SESSION_ERROR) == STAP_SESSION_RUNNING))";
336 : 1931 : s.op->newline() << "_stp_error (\"Skipped too many probes, check MAXSKIPPED or try again with stap -t for more details.\");";
337 : 1931 : s.op->newline(-1) << "}";
338 : : }
339 : :
340 : 1937 : s.op->newline() << "#if INTERRUPTIBLE";
341 : 1937 : s.op->newline() << "preempt_enable_no_resched ();";
342 : 1937 : s.op->newline() << "#else";
343 : 1937 : s.op->newline() << "local_irq_restore (flags);";
344 : 1937 : s.op->newline() << "#endif";
345 : :
346 : 1937 : s.op->newline() << "#endif // STP_ALIBI";
347 [ - + ]: 1937 : if (s.runtime_usermode_p())
348 : 0 : s.op->newline() << "errno = _stp_saved_errno;";
349 : 1937 : }
350 : :
351 : :
352 : : // ------------------------------------------------------------------------
353 : :
354 : : // ------------------------------------------------------------------------
355 : : // Dwarf derived probes. "We apologize for the inconvience."
356 : : // ------------------------------------------------------------------------
357 : :
358 [ + - ]: 2414 : static const string TOK_KERNEL("kernel");
359 [ + - ]: 2414 : static const string TOK_MODULE("module");
360 [ + - ]: 2414 : static const string TOK_FUNCTION("function");
361 [ + - ]: 2414 : static const string TOK_INLINE("inline");
362 [ + - ]: 2414 : static const string TOK_CALL("call");
363 [ + - ]: 2414 : static const string TOK_EXPORTED("exported");
364 [ + - ]: 2414 : static const string TOK_RETURN("return");
365 [ + - ]: 2414 : static const string TOK_MAXACTIVE("maxactive");
366 [ + - ]: 2414 : static const string TOK_STATEMENT("statement");
367 [ + - ]: 2414 : static const string TOK_ABSOLUTE("absolute");
368 [ + - ]: 2414 : static const string TOK_PROCESS("process");
369 [ + - ]: 2414 : static const string TOK_PROVIDER("provider");
370 [ + - ]: 2414 : static const string TOK_MARK("mark");
371 [ + - ]: 2414 : static const string TOK_TRACE("trace");
372 [ + - ]: 2414 : static const string TOK_LABEL("label");
373 [ + - ]: 2414 : static const string TOK_LIBRARY("library");
374 [ + - ]: 2414 : static const string TOK_PLT("plt");
375 : :
376 : : static int query_cu (Dwarf_Die * cudie, void * arg);
377 : : static void query_addr(Dwarf_Addr addr, dwarf_query *q);
378 : :
379 : : // Can we handle this query with just symbol-table info?
380 : : enum dbinfo_reqt
381 : : {
382 : : dbr_unknown,
383 : : dbr_none, // kernel.statement(NUM).absolute
384 : : dbr_need_symtab, // can get by with symbol table if there's no dwarf
385 : : dbr_need_dwarf
386 : : };
387 : :
388 : :
389 : : struct base_query; // forward decls
390 : : struct dwarf_query;
391 : : struct dwflpp;
392 : : struct symbol_table;
393 : :
394 : :
395 : : struct
396 : : symbol_table
397 : : {
398 : : module_info *mod_info; // associated module
399 : : map<string, func_info*> map_by_name;
400 : : multimap<Dwarf_Addr, func_info*> map_by_addr;
401 : : typedef multimap<Dwarf_Addr, func_info*>::iterator iterator_t;
402 : : typedef pair<iterator_t, iterator_t> range_t;
403 : : #ifdef __powerpc__
404 : : GElf_Word opd_section;
405 : : #endif
406 : : void add_symbol(const char *name, bool weak, bool descriptor,
407 : : Dwarf_Addr addr, Dwarf_Addr *high_addr);
408 : : enum info_status read_symbols(FILE *f, const string& path);
409 : : enum info_status read_from_elf_file(const string& path,
410 : : systemtap_session &sess);
411 : : enum info_status read_from_text_file(const string& path,
412 : : systemtap_session &sess);
413 : : enum info_status get_from_elf();
414 : : void prepare_section_rejection(Dwfl_Module *mod);
415 : : bool reject_section(GElf_Word section);
416 : : void purge_syscall_stubs();
417 : : func_info *lookup_symbol(const string& name);
418 : : Dwarf_Addr lookup_symbol_address(const string& name);
419 : : func_info *get_func_containing_address(Dwarf_Addr addr);
420 : : func_info *get_first_func();
421 : :
422 [ + - ]: 749 : symbol_table(module_info *mi) : mod_info(mi) {}
423 : : ~symbol_table();
424 : : };
425 : :
426 : 363250 : static bool null_die(Dwarf_Die *die)
427 : : {
428 : : static Dwarf_Die null;
429 [ + + ][ - + ]: 363250 : return (!die || !memcmp(die, &null, sizeof(null)));
430 : : }
431 : :
432 : :
433 : : enum
434 : : function_spec_type
435 : : {
436 : : function_alone,
437 : : function_and_file,
438 : : function_file_and_line
439 : : };
440 : :
441 : :
442 : : struct dwarf_builder;
443 : : struct dwarf_var_expanding_visitor;
444 : :
445 : :
446 : : // XXX: This class is a candidate for subclassing to separate
447 : : // the relocation vs non-relocation variants. Likewise for
448 : : // kprobe vs kretprobe variants.
449 : :
450 [ # # ][ # # ]: 0 : struct dwarf_derived_probe: public derived_probe
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
451 : : {
452 : : dwarf_derived_probe (const string& function,
453 : : const string& filename,
454 : : int line,
455 : : const string& module,
456 : : const string& section,
457 : : Dwarf_Addr dwfl_addr,
458 : : Dwarf_Addr addr,
459 : : dwarf_query & q,
460 : : Dwarf_Die* scope_die);
461 : :
462 : : string module;
463 : : string section;
464 : : Dwarf_Addr addr;
465 : : string path;
466 : : bool has_process;
467 : : bool has_return;
468 : : bool has_maxactive;
469 : : bool has_library;
470 : : long maxactive_val;
471 : : // dwarf_derived_probe_group::emit_module_decls uses this to emit sdt kprobe definition
472 : : string user_path;
473 : : string user_lib;
474 : : bool access_vars;
475 : :
476 : : unsigned saved_longs, saved_strings;
477 : : dwarf_derived_probe* entry_handler;
478 : :
479 : : void printsig (std::ostream &o) const;
480 : : virtual void join_group (systemtap_session& s);
481 : : void emit_probe_local_init(systemtap_session& s, translator_output * o);
482 : : void getargs(std::list<std::string> &arg_set) const;
483 : :
484 : : void emit_privilege_assertion (translator_output*);
485 : : void print_dupe_stamp(ostream& o);
486 : :
487 : : // Pattern registration helpers.
488 : : static void register_statement_variants(match_node * root,
489 : : dwarf_builder * dw,
490 : : privilege_t privilege);
491 : : static void register_function_variants(match_node * root,
492 : : dwarf_builder * dw,
493 : : privilege_t privilege);
494 : : static void register_function_and_statement_variants(systemtap_session& s,
495 : : match_node * root,
496 : : dwarf_builder * dw,
497 : : privilege_t privilege);
498 : : static void register_sdt_variants(systemtap_session& s,
499 : : match_node * root,
500 : : dwarf_builder * dw);
501 : : static void register_plt_variants(systemtap_session& s,
502 : : match_node * root,
503 : : dwarf_builder * dw);
504 : : static void register_patterns(systemtap_session& s);
505 : :
506 : : protected:
507 : 1 : dwarf_derived_probe(probe *base,
508 : : probe_point *location,
509 : : Dwarf_Addr addr,
510 : : bool has_return):
511 : : derived_probe(base, location), addr(addr), has_process(0),
512 : : has_return(has_return), has_maxactive(0), has_library(0),
513 : : maxactive_val(0), access_vars(false), saved_longs(0),
514 [ + - ][ + - ]: 1 : saved_strings(0), entry_handler(0)
[ + - ][ + - ]
[ + - ][ + - ]
515 : 1 : {}
516 : :
517 : : private:
518 : : list<string> args;
519 : : void saveargs(dwarf_query& q, Dwarf_Die* scope_die, Dwarf_Addr dwfl_addr);
520 : : };
521 : :
522 : :
523 [ # # ][ # # ]: 0 : struct uprobe_derived_probe: public dwarf_derived_probe
524 : : {
525 : : int pid; // 0 => unrestricted
526 : :
527 : 11862 : uprobe_derived_probe (const string& function,
528 : : const string& filename,
529 : : int line,
530 : : const string& module,
531 : : const string& section,
532 : : Dwarf_Addr dwfl_addr,
533 : : Dwarf_Addr addr,
534 : : dwarf_query & q,
535 : : Dwarf_Die* scope_die):
536 : : dwarf_derived_probe(function, filename, line, module, section,
537 [ + - ]: 11862 : dwfl_addr, addr, q, scope_die), pid(0)
538 : 11860 : {}
539 : :
540 : : // alternate constructor for process(PID).statement(ADDR).absolute
541 : 1 : uprobe_derived_probe (probe *base,
542 : : probe_point *location,
543 : : int pid,
544 : : Dwarf_Addr addr,
545 : : bool has_return):
546 [ + - ]: 1 : dwarf_derived_probe(base, location, addr, has_return), pid(pid)
547 : 1 : {}
548 : :
549 : : void join_group (systemtap_session& s);
550 : :
551 : : void emit_privilege_assertion (translator_output*);
552 : 12 : void print_dupe_stamp(ostream& o) { print_dupe_stamp_unprivileged_process_owner (o); }
553 : : void getargs(std::list<std::string> &arg_set) const;
554 : : void saveargs(int nargs);
555 : : private:
556 : : list<string> args;
557 : : };
558 : :
559 [ # # ][ # # ]: 0 : struct dwarf_derived_probe_group: public derived_probe_group
560 : : {
561 : : private:
562 : : multimap<string,dwarf_derived_probe*> probes_by_module;
563 : : typedef multimap<string,dwarf_derived_probe*>::iterator p_b_m_iterator;
564 : :
565 : : public:
566 [ + - ]: 385 : dwarf_derived_probe_group() {}
567 : : void enroll (dwarf_derived_probe* probe);
568 : : void emit_module_decls (systemtap_session& s);
569 : : void emit_module_init (systemtap_session& s);
570 : : void emit_module_refresh (systemtap_session& s);
571 : : void emit_module_exit (systemtap_session& s);
572 : : };
573 : :
574 : :
575 : : // Helper struct to thread through the dwfl callbacks.
576 : : struct base_query
577 : : {
578 : : base_query(dwflpp & dw, literal_map_t const & params);
579 : : base_query(dwflpp & dw, const string & module_val);
580 [ + - ][ + - ]: 56863 : virtual ~base_query() {}
[ - + ]
581 : :
582 : : systemtap_session & sess;
583 : : dwflpp & dw;
584 : :
585 : : // Parameter extractors.
586 : : static bool has_null_param(literal_map_t const & params,
587 : : string const & k);
588 : : static bool get_string_param(literal_map_t const & params,
589 : : string const & k, string & v);
590 : : static bool get_number_param(literal_map_t const & params,
591 : : string const & k, long & v);
592 : : static bool get_number_param(literal_map_t const & params,
593 : : string const & k, Dwarf_Addr & v);
594 : : static void query_library_callback (void *object, const char *data);
595 : : static void query_plt_callback (void *object, const char *link, size_t addr);
596 : : virtual void query_library (const char *data) = 0;
597 : : virtual void query_plt (const char *link, size_t addr) = 0;
598 : :
599 : :
600 : : // Extracted parameters.
601 : : bool has_kernel;
602 : : bool has_module;
603 : : bool has_process;
604 : : bool has_library;
605 : : bool has_plt;
606 : : bool has_statement;
607 : : string module_val; // has_kernel => module_val = "kernel"
608 : : string path; // executable path if module is a .so
609 : : string plt_val; // has_plt => plt wildcard
610 : :
611 : : virtual void handle_query_module() = 0;
612 : : };
613 : :
614 : :
615 : 46934 : base_query::base_query(dwflpp & dw, literal_map_t const & params):
616 [ + - ][ + - ]: 46934 : sess(dw.sess), dw(dw), has_library(false), has_plt(false), has_statement(false)
617 : : {
618 [ + - ]: 46934 : has_kernel = has_null_param (params, TOK_KERNEL);
619 [ + + ]: 46934 : if (has_kernel)
620 [ + - ]: 44799 : module_val = "kernel";
621 : :
622 [ + - ]: 46934 : has_module = get_string_param (params, TOK_MODULE, module_val);
623 [ + + ]: 46934 : if (has_module)
624 : 1999 : has_process = false;
625 : : else
626 : : {
627 [ + - ]: 44935 : string library_name;
628 : : long statement_num_val;
629 [ + - ]: 44935 : has_process = get_string_param(params, TOK_PROCESS, module_val);
630 [ + - ]: 44935 : has_library = get_string_param (params, TOK_LIBRARY, library_name);
631 [ + - ][ + + ]: 44935 : if ((has_plt = has_null_param (params, TOK_PLT)))
632 [ + - ]: 14 : plt_val = "*";
633 [ + - ]: 44921 : else has_plt = get_string_param (params, TOK_PLT, plt_val);
634 [ + + ]: 44935 : if (has_plt)
635 : 14 : sess.consult_symtab = true;
636 [ + - ]: 44935 : has_statement = get_number_param(params, TOK_STATEMENT, statement_num_val);
637 : :
638 [ + + ]: 44935 : if (has_process)
639 [ + - ][ + - ]: 136 : module_val = find_executable (module_val, sess.sysroot, sess.sysenv);
[ + - ][ + - ]
[ + - ]
640 [ + + ]: 44935 : if (has_library)
641 : : {
642 [ + - ][ + + ]: 12 : if (! contains_glob_chars (library_name))
643 : : {
644 [ + - ][ + - ]: 11 : path = path_remove_sysroot(sess, module_val);
[ + - ]
645 : : module_val = find_executable (library_name, sess.sysroot,
646 [ + - ][ + - ]: 11 : sess.sysenv, "LD_LIBRARY_PATH");
[ + - ][ + - ]
[ + - ]
647 [ + - ][ - + ]: 11 : if (module_val.find('/') == string::npos)
648 : : {
649 : : // We didn't find library_name so use iterate_over_libraries
650 [ # # ]: 0 : module_val = path;
651 [ # # ]: 0 : path = library_name;
652 : : }
653 : : }
654 : : else
655 [ + - ]: 1 : path = library_name;
656 [ + - ]: 44935 : }
657 : : }
658 : :
659 [ + + ][ + + ]: 46934 : assert (has_kernel || has_process || has_module);
[ - + ]
660 : 46934 : }
661 : :
662 : 9929 : base_query::base_query(dwflpp & dw, const string & module_val)
663 : : : sess(dw.sess), dw(dw), has_library(false), has_plt(false), has_statement(false),
664 [ + - ][ + - ]: 9929 : module_val(module_val)
665 : : {
666 : : // NB: This uses '/' to distinguish between kernel modules and userspace,
667 : : // which means that userspace modules won't get any PATH searching.
668 [ + - ][ + + ]: 9929 : if (module_val.find('/') == string::npos)
669 : : {
670 [ + - ]: 5291 : has_kernel = (module_val == TOK_KERNEL);
671 : 5291 : has_module = !has_kernel;
672 : 5291 : has_process = false;
673 : : }
674 : : else
675 : : {
676 : 4638 : has_kernel = has_module = false;
677 : 4638 : has_process = true;
678 : : }
679 : 9929 : }
680 : :
681 : : bool
682 : 326459 : base_query::has_null_param(literal_map_t const & params,
683 : : string const & k)
684 : : {
685 : 326459 : return derived_probe_builder::has_null_param(params, k);
686 : : }
687 : :
688 : :
689 : : bool
690 : 322511 : base_query::get_string_param(literal_map_t const & params,
691 : : string const & k, string & v)
692 : : {
693 : 322511 : return derived_probe_builder::get_param (params, k, v);
694 : : }
695 : :
696 : :
697 : : bool
698 : 91853 : base_query::get_number_param(literal_map_t const & params,
699 : : string const & k, long & v)
700 : : {
701 : : int64_t value;
702 [ + - ]: 91853 : bool present = derived_probe_builder::get_param (params, k, value);
703 : 91853 : v = (long) value;
704 : 91853 : return present;
705 : : }
706 : :
707 : :
708 : : bool
709 : 93836 : base_query::get_number_param(literal_map_t const & params,
710 : : string const & k, Dwarf_Addr & v)
711 : : {
712 : : int64_t value;
713 [ + - ]: 93836 : bool present = derived_probe_builder::get_param (params, k, value);
714 : 93836 : v = (Dwarf_Addr) value;
715 : 93836 : return present;
716 : : }
717 : :
718 [ + - ][ + - ]: 46918 : struct dwarf_query : public base_query
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
719 : : {
720 : : dwarf_query(probe * base_probe,
721 : : probe_point * base_loc,
722 : : dwflpp & dw,
723 : : literal_map_t const & params,
724 : : vector<derived_probe *> & results,
725 : : const string user_path,
726 : : const string user_lib);
727 : :
728 : : vector<derived_probe *> & results;
729 : : set<string> inlined_non_returnable; // function names
730 : : probe * base_probe;
731 : : probe_point * base_loc;
732 : : string user_path;
733 : : string user_lib;
734 : :
735 : : virtual void handle_query_module();
736 : : void query_module_dwarf();
737 : : void query_module_symtab();
738 : : void query_library (const char *data);
739 : : void query_plt (const char *entry, size_t addr);
740 : :
741 : : void add_probe_point(string const & funcname,
742 : : char const * filename,
743 : : int line,
744 : : Dwarf_Die *scope_die,
745 : : Dwarf_Addr addr);
746 : :
747 : : // Track addresses we've already seen in a given module
748 : : set<Dwarf_Addr> alias_dupes;
749 : :
750 : : // Track inlines we've already seen as well
751 : : // NB: this can't be compared just by entrypc, as inlines can overlap
752 : : set<inline_instance_info> inline_dupes;
753 : :
754 : : // Extracted parameters.
755 : : string function_val;
756 : :
757 : : bool has_function_str;
758 : : bool has_statement_str;
759 : : bool has_function_num;
760 : : bool has_statement_num;
761 : : string statement_str_val;
762 : : string function_str_val;
763 : : Dwarf_Addr statement_num_val;
764 : : Dwarf_Addr function_num_val;
765 : :
766 : : bool has_call;
767 : : bool has_exported;
768 : : bool has_inline;
769 : : bool has_return;
770 : :
771 : : bool has_maxactive;
772 : : long maxactive_val;
773 : :
774 : : bool has_label;
775 : : string label_val;
776 : :
777 : : bool has_relative;
778 : : long relative_val;
779 : :
780 : : bool has_absolute;
781 : :
782 : : bool has_mark;
783 : :
784 : : enum dbinfo_reqt dbinfo_reqt;
785 : : enum dbinfo_reqt assess_dbinfo_reqt();
786 : :
787 : : void parse_function_spec(const string & spec);
788 : : function_spec_type spec_type;
789 : : vector<string> scopes;
790 : : string function;
791 : : string file;
792 : : line_t line_type;
793 : : int line[2];
794 : : bool query_done; // Found exact match
795 : :
796 : : set<string> filtered_srcfiles;
797 : :
798 : : // Map official entrypc -> func_info object
799 : : inline_instance_map_t filtered_inlines;
800 : : func_info_map_t filtered_functions;
801 : : bool choose_next_line;
802 : : Dwarf_Addr entrypc_for_next_line;
803 : :
804 : : void query_module_functions ();
805 : : };
806 : :
807 : :
808 : : static void delete_session_module_cache (systemtap_session& s); // forward decl
809 : :
810 : :
811 : : struct dwarf_builder: public derived_probe_builder
812 : : {
813 : : map <string,dwflpp*> kern_dw; /* NB: key string could be a wildcard */
814 : : map <string,dwflpp*> user_dw;
815 : : string user_path;
816 : : string user_lib;
817 [ + - ][ + - ]: 1218 : dwarf_builder() {}
[ + - ][ + - ]
818 : :
819 : 56123 : dwflpp *get_kern_dw(systemtap_session& sess, const string& module)
820 : : {
821 [ + + ]: 56123 : if (kern_dw[module] == 0)
822 [ + + ]: 972 : kern_dw[module] = new dwflpp(sess, module, true); // might throw
823 : 56121 : return kern_dw[module];
824 : : }
825 : :
826 : 78 : dwflpp *get_user_dw(systemtap_session& sess, const string& module)
827 : : {
828 [ + + ]: 78 : if (user_dw[module] == 0)
829 [ + - ]: 67 : user_dw[module] = new dwflpp(sess, module, false); // might throw
830 : 78 : return user_dw[module];
831 : : }
832 : :
833 : : /* NB: not virtual, so can be called from dtor too: */
834 : 123060 : void dwarf_build_no_more (bool)
835 : : {
836 : 123060 : delete_map(kern_dw);
837 : 123060 : delete_map(user_dw);
838 : 123060 : }
839 : :
840 : 123060 : void build_no_more (systemtap_session &s)
841 : : {
842 : 123060 : dwarf_build_no_more (s.verbose > 3);
843 : 123060 : delete_session_module_cache (s);
844 : 123060 : }
845 : :
846 : 0 : ~dwarf_builder()
847 : 0 : {
848 [ # # ]: 0 : dwarf_build_no_more (false);
849 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
850 : :
851 : : virtual void build(systemtap_session & sess,
852 : : probe * base,
853 : : probe_point * location,
854 : : literal_map_t const & parameters,
855 : : vector<derived_probe *> & finished_results);
856 : : };
857 : :
858 : :
859 : 46918 : dwarf_query::dwarf_query(probe * base_probe,
860 : : probe_point * base_loc,
861 : : dwflpp & dw,
862 : : literal_map_t const & params,
863 : : vector<derived_probe *> & results,
864 : : const string user_path,
865 : : const string user_lib)
866 : : : base_query(dw, params), results(results),
867 : : base_probe(base_probe), base_loc(base_loc),
868 : : user_path(user_path), user_lib(user_lib), has_relative(false),
869 [ + - ][ + - ]: 46918 : relative_val(0), choose_next_line(false), entrypc_for_next_line(0)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
870 : : {
871 : : // Reduce the query to more reasonable semantic values (booleans,
872 : : // extracted strings, numbers, etc).
873 [ + - ]: 46918 : has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
874 [ + - ]: 46918 : has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
875 : :
876 [ + - ]: 46918 : has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
877 [ + - ]: 46918 : has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
878 : :
879 [ + - ]: 46918 : has_label = get_string_param(params, TOK_LABEL, label_val);
880 : :
881 [ + - ]: 46918 : has_call = has_null_param(params, TOK_CALL);
882 [ + - ]: 46918 : has_exported = has_null_param(params, TOK_EXPORTED);
883 [ + - ]: 46918 : has_inline = has_null_param(params, TOK_INLINE);
884 [ + - ]: 46918 : has_return = has_null_param(params, TOK_RETURN);
885 [ + - ]: 46918 : has_maxactive = get_number_param(params, TOK_MAXACTIVE, maxactive_val);
886 [ + - ]: 46918 : has_absolute = has_null_param(params, TOK_ABSOLUTE);
887 : 46918 : has_mark = false;
888 : :
889 [ + + ]: 46918 : if (has_function_str)
890 [ + - ]: 46799 : parse_function_spec(function_str_val);
891 [ + + ]: 119 : else if (has_statement_str)
892 [ + - ]: 27 : parse_function_spec(statement_str_val);
893 : :
894 : 46918 : dbinfo_reqt = assess_dbinfo_reqt();
895 : 46918 : query_done = false;
896 : 46918 : }
897 : :
898 : :
899 : : func_info_map_t *
900 : 2 : get_filtered_functions(dwarf_query *q)
901 : : {
902 : 2 : return &q->filtered_functions;
903 : : }
904 : :
905 : :
906 : : inline_instance_map_t *
907 : 0 : get_filtered_inlines(dwarf_query *q)
908 : : {
909 : 0 : return &q->filtered_inlines;
910 : : }
911 : :
912 : :
913 : : void
914 : 46693 : dwarf_query::query_module_dwarf()
915 : : {
916 [ + - ][ + + ]: 46693 : if (has_function_num || has_statement_num)
917 : : {
918 : : // If we have module("foo").function(0xbeef) or
919 : : // module("foo").statement(0xbeef), the address is relative
920 : : // to the start of the module, so we seek the function
921 : : // number plus the module's bias.
922 : : Dwarf_Addr addr = has_function_num ?
923 [ - + ]: 25 : function_num_val : statement_num_val;
924 : :
925 : : // These are raw addresses, we need to know what the elf_bias
926 : : // is to feed it to libdwfl based functions.
927 : : Dwarf_Addr elf_bias;
928 [ + - ]: 25 : Elf *elf = dwfl_module_getelf (dw.module, &elf_bias);
929 [ - + ]: 25 : assert(elf);
930 : 25 : addr += elf_bias;
931 [ + - ]: 25 : query_addr(addr, this);
932 : : }
933 : : else
934 : : {
935 : : // Otherwise if we have a function("foo") or statement("foo")
936 : : // specifier, we have to scan over all the CUs looking for
937 : : // the function(s) in question
938 [ + + ][ - + ]: 46668 : assert(has_function_str || has_statement_str);
939 : :
940 : : // For simple cases, no wildcard and no source:line, we can do a very
941 : : // quick function lookup in a module-wide cache.
942 [ + + + + : 138894 : if (spec_type == function_alone &&
+ - ][ + + ]
943 : 46574 : !dw.name_has_wildcard(function) &&
944 : 45652 : !startswith(function, "_Z"))
945 : 45652 : query_module_functions();
946 : : else
947 : 1016 : dw.iterate_over_cus(&query_cu, this, false);
948 : : }
949 : 46693 : }
950 : :
951 : : static void query_func_info (Dwarf_Addr entrypc, func_info & fi,
952 : : dwarf_query * q);
953 : :
954 : : void
955 : 0 : dwarf_query::query_module_symtab()
956 : : {
957 : : // Get the symbol table if it's necessary, sufficient, and not already got.
958 [ # # ]: 0 : if (dbinfo_reqt == dbr_need_dwarf)
959 : 0 : return;
960 : :
961 : 0 : module_info *mi = dw.mod_info;
962 [ # # ]: 0 : if (dbinfo_reqt == dbr_need_symtab)
963 : : {
964 [ # # ]: 0 : if (mi->symtab_status == info_unknown)
965 : 0 : mi->get_symtab(this);
966 [ # # ]: 0 : if (mi->symtab_status == info_absent)
967 : 0 : return;
968 : : }
969 : :
970 : 0 : func_info *fi = NULL;
971 : 0 : symbol_table *sym_table = mi->sym_table;
972 : :
973 [ # # ]: 0 : if (has_function_str)
974 : : {
975 : : // Per dwarf_query::assess_dbinfo_reqt()...
976 [ # # ]: 0 : assert(spec_type == function_alone);
977 [ # # ]: 0 : if (dw.name_has_wildcard(function_str_val))
978 : : {
979 : : // Until we augment the blacklist sufficently...
980 [ # # ][ # # ]: 0 : if (function_str_val.find_first_not_of("*?") == string::npos)
981 : : {
982 : : // e.g., kernel.function("*")
983 [ # # ][ # # ]: 0 : cerr << _F("Error: Pattern '%s' matches every single "
[ # # ][ # # ]
984 : : "instruction address in the symbol table,\n"
985 [ # # ]: 0 : "some of which aren't even functions.\n", function_str_val.c_str()) << endl;
986 : : return;
987 : : }
988 : 0 : symbol_table::iterator_t iter;
989 [ # # ][ # # ]: 0 : for (iter = sym_table->map_by_addr.begin();
990 [ # # ]: 0 : iter != sym_table->map_by_addr.end();
991 : : ++iter)
992 : : {
993 [ # # ]: 0 : fi = iter->second;
994 [ # # ]: 0 : if (!null_die(&fi->die))
995 : 0 : continue; // already handled in query_module_dwarf()
996 [ # # ][ # # ]: 0 : if (dw.function_name_matches_pattern(fi->name, function_str_val))
997 [ # # ]: 0 : query_func_info(fi->addr, *fi, this);
998 : : }
999 : : }
1000 : : else
1001 : : {
1002 : 0 : fi = sym_table->lookup_symbol(function_str_val);
1003 [ # # ][ # # ]: 0 : if (fi && !fi->descriptor && null_die(&fi->die))
[ # # ][ # # ]
1004 : 0 : query_func_info(fi->addr, *fi, this);
1005 : : }
1006 : : }
1007 : : else
1008 : : {
1009 [ # # ][ # # ]: 0 : assert(has_function_num || has_statement_num);
1010 : : // Find the "function" in which the indicated address resides.
1011 : : Dwarf_Addr addr =
1012 [ # # ]: 0 : (has_function_num ? function_num_val : statement_num_val);
1013 [ # # ]: 0 : if (has_plt)
1014 : : {
1015 : : // Use the raw address from the .plt
1016 : 0 : fi = sym_table->get_first_func();
1017 : 0 : fi->addr = addr;
1018 : : }
1019 : : else
1020 : 0 : fi = sym_table->get_func_containing_address(addr);
1021 : :
1022 [ # # ]: 0 : if (!fi)
1023 : : {
1024 : 0 : sess.print_warning(_F("address %#" PRIx64 " out of range for module %s",
1025 [ # # ]: 0 : addr, dw.module_name.c_str()));
1026 : 0 : return;
1027 : : }
1028 [ # # ]: 0 : if (!null_die(&fi->die))
1029 : : {
1030 : : // addr looks like it's in the compilation unit containing
1031 : : // the indicated function, but query_module_dwarf() didn't
1032 : : // match addr to any compilation unit, so addr must be
1033 : : // above that cu's address range.
1034 : 0 : sess.print_warning(_F("address %#" PRIx64 " maps to no known compilation unit in module %s",
1035 [ # # ]: 0 : addr, dw.module_name.c_str()));
1036 : 0 : return;
1037 : : }
1038 : 0 : query_func_info(fi->addr, *fi, this);
1039 : : }
1040 : : }
1041 : :
1042 : : void
1043 : 46701 : dwarf_query::handle_query_module()
1044 : : {
1045 [ + + ][ + - ]: 46701 : bool report = dbinfo_reqt == dbr_need_dwarf || !sess.consult_symtab;
1046 : 46701 : dw.get_module_dwarf(false, report);
1047 : :
1048 : : // prebuild the symbol table to resolve aliases
1049 : 46701 : dw.mod_info->get_symtab(this);
1050 : :
1051 : : // reset the dupe-checking for each new module
1052 : 46701 : alias_dupes.clear();
1053 : 46701 : inline_dupes.clear();
1054 : :
1055 [ + + ]: 46701 : if (dw.mod_info->dwarf_status == info_present)
1056 : 46693 : query_module_dwarf();
1057 : :
1058 : : // Consult the symbol table if we haven't found all we're looking for.
1059 : : // asm functions can show up in the symbol table but not in dwarf.
1060 [ - + ][ # # ]: 46701 : if (sess.consult_symtab && !query_done)
1061 : 0 : query_module_symtab();
1062 : 46701 : }
1063 : :
1064 : :
1065 : : void
1066 : 46826 : dwarf_query::parse_function_spec(const string & spec)
1067 : : {
1068 : 46826 : line_type = ABSOLUTE;
1069 : 46826 : line[0] = line[1] = 0;
1070 : :
1071 : : size_t src_pos, line_pos, dash_pos, scope_pos;
1072 : :
1073 : : // look for named scopes
1074 : 46826 : scope_pos = spec.rfind("::");
1075 [ - + ]: 46826 : if (scope_pos != string::npos)
1076 : : {
1077 [ # # ]: 0 : tokenize_cxx(spec.substr(0, scope_pos), scopes);
1078 : 0 : scope_pos += 2;
1079 : : }
1080 : : else
1081 : 46826 : scope_pos = 0;
1082 : :
1083 : : // look for a source separator
1084 : 46826 : src_pos = spec.find('@', scope_pos);
1085 [ + + ]: 46826 : if (src_pos == string::npos)
1086 : : {
1087 [ + - ]: 46721 : function = spec.substr(scope_pos);
1088 : 46721 : spec_type = function_alone;
1089 : : }
1090 : : else
1091 : : {
1092 [ + - ]: 105 : function = spec.substr(scope_pos, src_pos - scope_pos);
1093 : :
1094 : : // look for a line-number separator
1095 : 105 : line_pos = spec.find_first_of(":+", src_pos);
1096 [ + + ]: 105 : if (line_pos == string::npos)
1097 : : {
1098 [ + - ]: 82 : file = spec.substr(src_pos + 1);
1099 : 82 : spec_type = function_and_file;
1100 : : }
1101 : : else
1102 : : {
1103 [ + - ]: 23 : file = spec.substr(src_pos + 1, line_pos - src_pos - 1);
1104 : :
1105 : : // classify the line spec
1106 : 23 : spec_type = function_file_and_line;
1107 [ + + ]: 23 : if (spec[line_pos] == '+')
1108 : 5 : line_type = RELATIVE;
1109 [ + + + - ]: 24 : else if (spec[line_pos + 1] == '*' &&
[ + + ]
1110 : 6 : spec.length() == line_pos + 2)
1111 : 6 : line_type = WILDCARD;
1112 : : else
1113 : 12 : line_type = ABSOLUTE;
1114 : :
1115 [ + + ]: 23 : if (line_type != WILDCARD)
1116 : : try
1117 : : {
1118 : : // try to parse either N or N-M
1119 [ + - ]: 17 : dash_pos = spec.find('-', line_pos + 1);
1120 [ + - ]: 17 : if (dash_pos == string::npos)
1121 [ + - ][ + - ]: 17 : line[0] = line[1] = lex_cast<int>(spec.substr(line_pos + 1));
[ + - ]
1122 : : else
1123 : : {
1124 : 0 : line_type = RANGE;
1125 : : line[0] = lex_cast<int>(spec.substr(line_pos + 1,
1126 [ # # ][ # # ]: 0 : dash_pos - line_pos - 1));
[ # # ]
1127 [ # # ][ # # ]: 0 : line[1] = lex_cast<int>(spec.substr(dash_pos + 1));
[ # # ][ # # ]
1128 : : }
1129 : : }
1130 : : catch (runtime_error & exn)
1131 : : {
1132 : : goto bad;
1133 : : }
1134 : : }
1135 : : }
1136 : :
1137 [ + - ]: 46931 : if (function.empty() ||
[ + + - + ]
[ - + ]
1138 : 105 : (spec_type != function_alone && file.empty()))
1139 : 0 : goto bad;
1140 : :
1141 [ - + ]: 46826 : if (sess.verbose > 2)
1142 : : {
1143 : : //clog << "parsed '" << spec << "'";
1144 [ # # ]: 0 : clog << _F("parse '%s'", spec.c_str());
1145 : :
1146 [ # # ]: 0 : if (!scopes.empty())
1147 : 0 : clog << ", scope '" << scopes[0] << "'";
1148 [ # # ]: 0 : for (unsigned i = 1; i < scopes.size(); ++i)
1149 : 0 : clog << "::'" << scopes[i] << "'";
1150 : :
1151 : 0 : clog << ", func '" << function << "'";
1152 : :
1153 [ # # ]: 0 : if (spec_type != function_alone)
1154 : 0 : clog << ", file '" << file << "'";
1155 : :
1156 [ # # ]: 0 : if (spec_type == function_file_and_line)
1157 : : {
1158 : 0 : clog << ", line ";
1159 [ # # # # : 0 : switch (line_type)
# ]
1160 : : {
1161 : : case ABSOLUTE:
1162 : 0 : clog << line[0];
1163 : 0 : break;
1164 : :
1165 : : case RELATIVE:
1166 : 0 : clog << "+" << line[0];
1167 : 0 : break;
1168 : :
1169 : : case RANGE:
1170 : 0 : clog << line[0] << " - " << line[1];
1171 : 0 : break;
1172 : :
1173 : : case WILDCARD:
1174 : 0 : clog << "*";
1175 : 0 : break;
1176 : : }
1177 : : }
1178 : :
1179 : 0 : clog << endl;
1180 : : }
1181 : :
1182 : 46826 : return;
1183 : :
1184 : : bad:
1185 : 0 : throw semantic_error(_F("malformed specification '%s'", spec.c_str()),
1186 [ # # ][ # # ]: 0 : base_probe->tok);
[ # # ]
1187 : : }
1188 : :
1189 : 12257 : string path_remove_sysroot(const systemtap_session& sess, const string& path)
1190 : : {
1191 : : size_t pos;
1192 : 12257 : string retval = path;
1193 [ + - ][ - + ]: 12257 : if (!sess.sysroot.empty() &&
[ # # ][ # # ]
[ - + ]
1194 : 0 : (pos = retval.find(sess.sysroot)) != string::npos)
1195 [ # # ][ # # ]: 0 : retval.replace(pos, sess.sysroot.length(), "/");
1196 : 12257 : return retval;
1197 : : }
1198 : :
1199 : : void
1200 : 377321 : dwarf_query::add_probe_point(const string& dw_funcname,
1201 : : const char* filename,
1202 : : int line,
1203 : : Dwarf_Die* scope_die,
1204 : : Dwarf_Addr addr)
1205 : : {
1206 [ + - ]: 377321 : string reloc_section; // base section for relocation purposes
1207 : : Dwarf_Addr reloc_addr; // relocated
1208 : 377321 : const string& module = dw.module_name; // "kernel" or other
1209 [ + - ]: 377321 : string funcname = dw_funcname;
1210 : :
1211 [ - + ]: 377321 : assert (! has_absolute); // already handled in dwarf_builder::build()
1212 : :
1213 [ + - ]: 377321 : if (!has_plt)
1214 [ + - ]: 377321 : reloc_addr = dw.relocate_address(addr, reloc_section);
1215 : : else
1216 : : {
1217 : : // Set the reloc_section but use the plt entry for reloc_addr
1218 [ # # ]: 0 : dw.relocate_address(addr, reloc_section);
1219 : 0 : reloc_addr = addr;
1220 : : }
1221 : :
1222 : : // If we originally used the linkage name, then let's call it that way
1223 : : const char* linkage_name;
1224 [ + - ][ + - ]: 377321 : if (scope_die && startswith (this->function, "_Z")
[ - + ][ # # ]
[ # # ][ - + ]
1225 : : && (linkage_name = dwarf_linkage_name (scope_die)))
1226 [ # # ]: 0 : funcname = linkage_name;
1227 : :
1228 [ + + ]: 377321 : if (sess.verbose > 1)
1229 : : {
1230 [ + - ][ + - ]: 296 : clog << _("probe ") << funcname << "@" << filename << ":" << line;
[ + - ][ + - ]
[ + - ][ + - ]
1231 [ + - ][ + - ]: 296 : if (string(module) == TOK_KERNEL)
[ + - ][ + - ]
1232 [ + - ]: 296 : clog << _(" kernel");
1233 [ # # ]: 0 : else if (has_module)
1234 [ # # ][ # # ]: 0 : clog << _(" module=") << module;
1235 [ # # ]: 0 : else if (has_process)
1236 [ # # ][ # # ]: 0 : clog << _(" process=") << module;
1237 [ + - ][ + - ]: 296 : if (reloc_section != "") clog << " reloc=" << reloc_section;
[ + - ][ + - ]
1238 [ + - ][ + - ]: 296 : clog << " pc=0x" << hex << addr << dec;
[ + - ][ + - ]
1239 : : }
1240 : :
1241 : : bool bad = dw.blacklisted_p (funcname, filename, line, module,
1242 [ + - ][ + - ]: 377321 : addr, has_return);
[ + - ]
1243 [ + + ]: 377321 : if (sess.verbose > 1)
1244 [ + - ]: 296 : clog << endl;
1245 : :
1246 [ + - ][ + + ]: 377321 : if (module == TOK_KERNEL)
1247 : : {
1248 : : // PR 4224: adapt to relocatable kernel by subtracting the _stext address here.
1249 : 293180 : reloc_addr = addr - sess.sym_stext;
1250 [ + - ]: 293180 : reloc_section = "_stext"; // a message to runtime's _stp_module_relocate
1251 : : }
1252 : :
1253 [ + + ]: 377321 : if (! bad)
1254 : : {
1255 [ + - ]: 328888 : sess.unwindsym_modules.insert (module);
1256 : :
1257 [ + + ]: 328888 : if (has_process)
1258 : : {
1259 [ + - ]: 11813 : string module_tgt = path_remove_sysroot(sess, module);
1260 : : results.push_back (new uprobe_derived_probe(funcname, filename, line,
1261 : : module_tgt, reloc_section, addr, reloc_addr,
1262 [ + - ][ + - ]: 11813 : *this, scope_die));
[ + + ][ + - ]
[ + - ][ + - ]
1263 : : }
1264 : : else
1265 : : {
1266 [ + + ][ - + ]: 317075 : assert (has_kernel || has_module);
1267 : : results.push_back (new dwarf_derived_probe(funcname, filename, line,
1268 : : module, reloc_section, addr, reloc_addr,
1269 [ + - ][ + - ]: 317075 : *this, scope_die));
[ + + ][ + - ]
[ + - ]
1270 : : }
1271 [ + - ][ + - ]: 377321 : }
1272 : 377313 : }
1273 : :
1274 : : enum dbinfo_reqt
1275 : 46918 : dwarf_query::assess_dbinfo_reqt()
1276 : : {
1277 [ + + ]: 46918 : if (has_absolute)
1278 : : {
1279 : : // kernel.statement(NUM).absolute
1280 : 5 : return dbr_none;
1281 : : }
1282 [ + + ]: 46913 : if (has_inline)
1283 : : {
1284 : : // kernel.function("f").inline or module("m").function("f").inline
1285 : 226 : return dbr_need_dwarf;
1286 : : }
1287 [ + + ][ + + ]: 46687 : if (has_function_str && spec_type == function_alone)
1288 : : {
1289 : : // kernel.function("f") or module("m").function("f")
1290 : 46494 : return dbr_need_symtab;
1291 : : }
1292 [ + + ]: 193 : if (has_statement_num)
1293 : : {
1294 : : // kernel.statement(NUM) or module("m").statement(NUM)
1295 : : // Technically, all we need is the module offset (or _stext, for
1296 : : // the kernel). But for that we need either the ELF file or (for
1297 : : // _stext) the symbol table. In either case, the symbol table
1298 : : // is available, and that allows us to map the NUM (address)
1299 : : // to a function, which is goodness.
1300 : 73 : return dbr_need_symtab;
1301 : : }
1302 [ - + ]: 120 : if (has_function_num)
1303 : : {
1304 : : // kernel.function(NUM) or module("m").function(NUM)
1305 : : // Need the symbol table so we can back up from NUM to the
1306 : : // start of the function.
1307 : 0 : return dbr_need_symtab;
1308 : : }
1309 : : // Symbol table tells us nothing about source files or line numbers.
1310 : 46918 : return dbr_need_dwarf;
1311 : : }
1312 : :
1313 : :
1314 : : // The critical determining factor when interpreting a pattern
1315 : : // string is, perhaps surprisingly: "presence of a lineno". The
1316 : : // presence of a lineno changes the search strategy completely.
1317 : : //
1318 : : // Compare the two cases:
1319 : : //
1320 : : // 1. {statement,function}(foo@file.c:lineno)
1321 : : // - find the files matching file.c
1322 : : // - in each file, find the functions matching foo
1323 : : // - query the file for line records matching lineno
1324 : : // - iterate over the line records,
1325 : : // - and iterate over the functions,
1326 : : // - if(haspc(function.DIE, line.addr))
1327 : : // - if looking for statements: probe(lineno.addr)
1328 : : // - if looking for functions: probe(function.{entrypc,return,etc.})
1329 : : //
1330 : : // 2. {statement,function}(foo@file.c)
1331 : : // - find the files matching file.c
1332 : : // - in each file, find the functions matching foo
1333 : : // - probe(function.{entrypc,return,etc.})
1334 : : //
1335 : : // Thus the first decision we make is based on the presence of a
1336 : : // lineno, and we enter entirely different sets of callbacks
1337 : : // depending on that decision.
1338 : : //
1339 : : // Note that the first case is a generalization fo the second, in that
1340 : : // we could theoretically search through line records for matching
1341 : : // file names (a "table scan" in rdbms lingo). Luckily, file names
1342 : : // are already cached elsewhere, so we can do an "index scan" as an
1343 : : // optimization.
1344 : :
1345 : : static void
1346 : 377321 : query_statement (string const & func,
1347 : : char const * file,
1348 : : int line,
1349 : : Dwarf_Die *scope_die,
1350 : : Dwarf_Addr stmt_addr,
1351 : : dwarf_query * q)
1352 : : {
1353 : : try
1354 : : {
1355 : : q->add_probe_point(func, file ? file : "",
1356 [ + - ][ + + ]: 377321 : line, scope_die, stmt_addr);
1357 : : }
1358 [ - + ]: 16 : catch (const semantic_error& e)
1359 : : {
1360 [ - + ]: 8 : q->sess.print_error (e);
1361 : : }
1362 : 377321 : }
1363 : :
1364 : : static void
1365 : 25 : query_addr(Dwarf_Addr addr, dwarf_query *q)
1366 : : {
1367 : 25 : dwflpp &dw = q->dw;
1368 : :
1369 [ - + ]: 25 : if (q->sess.verbose > 2)
1370 [ # # ][ # # ]: 0 : clog << "query_addr 0x" << hex << addr << dec << endl;
[ # # ][ # # ]
[ # # ]
1371 : :
1372 : : // First pick which CU contains this address
1373 [ + - ]: 25 : Dwarf_Die* cudie = dw.query_cu_containing_address(addr);
1374 [ + - ]: 25 : if (!cudie) // address could be wildly out of range
1375 : : return;
1376 [ + - ]: 25 : dw.focus_on_cu(cudie);
1377 : :
1378 : : // Now compensate for the dw bias
1379 : 25 : addr -= dw.module_bias;
1380 : :
1381 : : // Per PR5787, we look up the scope die even for
1382 : : // statement_num's, for blacklist sensitivity and $var
1383 : : // resolution purposes.
1384 : :
1385 : : // Find the scopes containing this address
1386 [ + - ]: 25 : vector<Dwarf_Die> scopes = dw.getscopes(addr);
1387 [ + - ][ - + ]: 25 : if (scopes.empty())
1388 : : return;
1389 : :
1390 : : // Look for the innermost containing function
1391 : 25 : Dwarf_Die *fnscope = NULL;
1392 [ + - ]: 49 : for (size_t i = 0; i < scopes.size(); ++i)
1393 : : {
1394 [ + - ]: 49 : int tag = dwarf_tag(&scopes[i]);
1395 [ + + ][ - + ]: 49 : if ((tag == DW_TAG_subprogram && !q->has_inline) ||
[ - + ][ # # ]
[ # # ][ # # ]
1396 : : (tag == DW_TAG_inlined_subroutine &&
1397 : 0 : !q->has_call && !q->has_return && !q->has_exported))
1398 : : {
1399 : 25 : fnscope = &scopes[i];
1400 : 25 : break;
1401 : : }
1402 : : }
1403 [ - + ]: 25 : if (!fnscope)
1404 : : return;
1405 [ + - ]: 25 : dw.focus_on_function(fnscope);
1406 : :
1407 [ - + ]: 25 : Dwarf_Die *scope = q->has_function_num ? fnscope : &scopes[0];
1408 : :
1409 [ + - ]: 25 : const char *file = dwarf_decl_file(fnscope);
1410 : : int line;
1411 [ + - ]: 25 : dwarf_decl_line(fnscope, &line);
1412 : :
1413 : : // Function probes should reset the addr to the function entry
1414 : : // and possibly perform prologue searching
1415 [ - + ]: 25 : if (q->has_function_num)
1416 : : {
1417 [ # # ]: 0 : dw.die_entrypc(fnscope, &addr);
1418 [ # # ][ # # ]: 0 : if (dwarf_tag(fnscope) == DW_TAG_subprogram &&
[ # # ][ # # ]
[ # # ]
1419 : : (q->sess.prologue_searching || q->has_process)) // PR 6871
1420 : : {
1421 [ # # ]: 0 : func_info func;
1422 : 0 : func.die = *fnscope;
1423 [ # # ]: 0 : func.name = dw.function_name;
1424 : 0 : func.decl_file = file;
1425 : 0 : func.decl_line = line;
1426 : 0 : func.entrypc = addr;
1427 : :
1428 [ # # ]: 0 : func_info_map_t funcs(1, func);
1429 [ # # ]: 0 : dw.resolve_prologue_endings (funcs);
1430 [ # # ]: 0 : if (q->has_return) // PR13200
1431 : : {
1432 [ # # ]: 0 : if (q->sess.verbose > 2)
1433 [ # # ][ # # ]: 0 : clog << "ignoring prologue for .return probes" << endl;
1434 : : }
1435 : : else
1436 : : {
1437 [ # # ]: 0 : if (funcs[0].prologue_end)
1438 : 0 : addr = funcs[0].prologue_end;
1439 [ # # ][ # # ]: 0 : }
1440 : : }
1441 : : }
1442 : : else
1443 : : {
1444 [ + - ]: 25 : dwarf_line_t address_line(dwarf_getsrc_die(cudie, addr));
1445 [ + - ]: 25 : if (address_line)
1446 : : {
1447 [ + - ]: 25 : file = address_line.linesrc();
1448 [ + - ]: 25 : line = address_line.lineno();
1449 : : }
1450 : :
1451 : : // Verify that a raw address matches the beginning of a
1452 : : // statement. This is a somewhat lame check that the address
1453 : : // is at the start of an assembly instruction. Mark probes are in the
1454 : : // middle of a macro and thus not strictly at a statement beginning.
1455 : : // Guru mode may override this check.
1456 [ + + ][ + - ]: 25 : if (!q->has_mark && (!address_line || address_line.addr() != addr))
[ + - ][ - + ]
[ - + ]
1457 : : {
1458 [ # # ]: 0 : stringstream msg;
1459 [ # # ][ # # ]: 0 : msg << _F("address %#" PRIx64 " does not match the beginning of a statement",
1460 [ # # ]: 0 : addr);
1461 [ # # ]: 0 : if (address_line)
1462 [ # # ][ # # ]: 0 : msg << _F(" (try %#" PRIx64 ")", address_line.addr());
[ # # ][ # # ]
1463 : : else
1464 [ # # ][ # # ]: 0 : msg << _F(" (no line info found for '%s', in module '%s')",
[ # # ][ # # ]
[ # # ][ # # ]
1465 [ # # ]: 0 : dw.cu_name().c_str(), dw.module_name.c_str());
1466 [ # # ]: 0 : if (! q->sess.guru_mode)
1467 [ # # ][ # # ]: 0 : throw semantic_error(msg.str());
1468 : : else
1469 [ # # ][ # # ]: 25 : q->sess.print_warning(msg.str());
[ # # ][ # # ]
1470 : : }
1471 : : }
1472 : :
1473 : : // Build a probe at this point
1474 [ + - ][ + - ]: 25 : query_statement(dw.function_name, file, line, scope, addr, q);
[ + - ]
1475 : : }
1476 : :
1477 : : static void
1478 : 6 : query_label (string const & func,
1479 : : char const * label,
1480 : : char const * file,
1481 : : int line,
1482 : : Dwarf_Die *scope_die,
1483 : : Dwarf_Addr stmt_addr,
1484 : : dwarf_query * q)
1485 : : {
1486 [ + - ][ - + ]: 6 : assert (q->has_statement_str || q->has_function_str);
1487 : :
1488 : 6 : size_t i = q->results.size();
1489 : :
1490 : : // weed out functions whose decl_file isn't one of
1491 : : // the source files that we actually care about
1492 [ - + ][ # # ]: 12 : if (q->spec_type != function_alone &&
[ + - ]
1493 [ # # ][ # # ]: 6 : q->filtered_srcfiles.count(file) == 0)
[ - + ][ # # ]
[ - + ]
[ # # # # ]
1494 : 6 : return;
1495 : :
1496 [ + - ]: 6 : query_statement(func, file, line, scope_die, stmt_addr, q);
1497 : :
1498 : : // after the fact, insert the label back into the derivation chain
1499 : : probe_point::component* ppc =
1500 [ + - ][ + - ]: 6 : new probe_point::component(TOK_LABEL, new literal_string (label));
[ + - ][ + - ]
[ + - ][ + - ]
1501 [ + + ]: 12 : for (; i < q->results.size(); ++i)
1502 : : {
1503 : 6 : derived_probe* p = q->results[i];
1504 [ + - ][ + - ]: 6 : probe_point* pp = new probe_point(*p->locations[0]);
1505 [ + - ]: 6 : pp->components.push_back (ppc);
1506 [ + - ]: 6 : p->base = p->base->create_alias(p->locations[0], pp);
1507 : : }
1508 : : }
1509 : :
1510 : : static void
1511 : 213465 : query_inline_instance_info (inline_instance_info & ii,
1512 : : dwarf_query * q)
1513 : : {
1514 : : try
1515 : : {
1516 [ - + ]: 213465 : assert (! q->has_return); // checked by caller already
1517 [ - + ]: 213465 : if (q->sess.verbose>2)
1518 [ # # ][ # # ]: 0 : clog << _F("querying entrypc %#" PRIx64 " of instance of inline '%s'\n",
[ # # ]
1519 [ # # ]: 0 : ii.entrypc, ii.name.c_str());
1520 : : query_statement (ii.name, ii.decl_file, ii.decl_line,
1521 [ + - ]: 213465 : &ii.die, ii.entrypc, q);
1522 : : }
1523 [ # # ]: : catch (semantic_error &e)
1524 : : {
1525 [ # # ]: : q->sess.print_error (e);
1526 : : }
1527 : 213465 : }
1528 : :
1529 : : static void
1530 : 163785 : query_func_info (Dwarf_Addr entrypc,
1531 : : func_info & fi,
1532 : : dwarf_query * q)
1533 : : {
1534 : : try
1535 : : {
1536 [ + + ]: 163785 : if (q->has_return)
1537 : : {
1538 : : // NB. dwarf_derived_probe::emit_registrations will emit a
1539 : : // kretprobe based on the entrypc in this case.
1540 [ + + ][ + - ]: 48067 : if (fi.prologue_end != 0 && q->has_return) // PR13200
1541 : : {
1542 [ - + ]: 1 : if (q->sess.verbose > 2)
1543 [ # # ][ # # ]: 0 : clog << "ignoring prologue for .return probes" << endl;
1544 : : }
1545 : : query_statement (fi.name, fi.decl_file, fi.decl_line,
1546 [ + - ]: 48067 : &fi.die, entrypc, q);
1547 : : }
1548 : : else
1549 : : {
1550 [ + + ]: 115718 : if (fi.prologue_end != 0)
1551 : : {
1552 : : query_statement (fi.name, fi.decl_file, fi.decl_line,
1553 [ + - ]: 11604 : &fi.die, fi.prologue_end, q);
1554 : : }
1555 : : else
1556 : : {
1557 : : query_statement (fi.name, fi.decl_file, fi.decl_line,
1558 [ + - ]: 104114 : &fi.die, entrypc, q);
1559 : : }
1560 : : }
1561 : : }
1562 [ # # ]: : catch (semantic_error &e)
1563 : : {
1564 [ # # ]: : q->sess.print_error (e);
1565 : : }
1566 : 163785 : }
1567 : :
1568 : :
1569 : : static void
1570 : 0 : query_srcfile_label (const dwarf_line_t& line, void * arg)
1571 : : {
1572 : 0 : dwarf_query * q = static_cast<dwarf_query *>(arg);
1573 : :
1574 : 0 : Dwarf_Addr addr = line.addr();
1575 : :
1576 [ # # ][ # # ]: 0 : for (func_info_map_t::iterator i = q->filtered_functions.begin();
[ # # ]
1577 [ # # ]: 0 : i != q->filtered_functions.end(); ++i)
1578 [ # # ][ # # ]: 0 : if (q->dw.die_has_pc (i->die, addr))
1579 : 0 : q->dw.iterate_over_labels (&i->die, q->label_val, i->name,
1580 [ # # ]: 0 : q, query_label);
1581 : :
1582 [ # # ][ # # ]: 0 : for (inline_instance_map_t::iterator i = q->filtered_inlines.begin();
[ # # ]
1583 [ # # ]: 0 : i != q->filtered_inlines.end(); ++i)
1584 [ # # ][ # # ]: 0 : if (q->dw.die_has_pc (i->die, addr))
1585 : 0 : q->dw.iterate_over_labels (&i->die, q->label_val, i->name,
1586 [ # # ]: 0 : q, query_label);
1587 : 0 : }
1588 : :
1589 : : static void
1590 : 762 : query_srcfile_line (const dwarf_line_t& line, void * arg)
1591 : : {
1592 : 762 : dwarf_query * q = static_cast<dwarf_query *>(arg);
1593 : :
1594 : 762 : Dwarf_Addr addr = line.addr();
1595 : :
1596 : 762 : int lineno = line.lineno();
1597 : :
1598 [ + - ][ + - ]: 3046 : for (func_info_map_t::iterator i = q->filtered_functions.begin();
[ + + ]
1599 [ + - ]: 1523 : i != q->filtered_functions.end(); ++i)
1600 : : {
1601 [ + - ][ + + ]: 761 : if (q->dw.die_has_pc (i->die, addr))
1602 : : {
1603 [ - + ]: 39 : if (q->sess.verbose>3)
1604 [ # # ]: 0 : clog << _("function DIE lands on srcfile\n");
1605 [ + - ]: 39 : if (q->has_statement_str)
1606 : : {
1607 : : Dwarf_Die scope;
1608 [ + - ]: 39 : q->dw.inner_die_containing_pc(i->die, addr, scope);
1609 : 39 : query_statement (i->name, i->decl_file,
1610 : : lineno, // NB: not q->line !
1611 [ + - ]: 39 : &scope, addr, q);
1612 : : }
1613 : : else
1614 [ # # ]: 0 : query_func_info (i->entrypc, *i, q);
1615 : : }
1616 : : }
1617 : :
1618 [ + - ][ + + ]: 1526 : for (inline_instance_map_t::iterator i
1619 [ + - ]: 762 : = q->filtered_inlines.begin();
1620 [ + - ]: 763 : i != q->filtered_inlines.end(); ++i)
1621 : : {
1622 [ + - ][ + - ]: 1 : if (q->dw.die_has_pc (i->die, addr))
1623 : : {
1624 [ - + ]: 1 : if (q->sess.verbose>3)
1625 [ # # ]: 0 : clog << _("inline instance DIE lands on srcfile\n");
1626 [ + - ]: 1 : if (q->has_statement_str)
1627 : : {
1628 : : Dwarf_Die scope;
1629 [ + - ]: 1 : q->dw.inner_die_containing_pc(i->die, addr, scope);
1630 : 1 : query_statement (i->name, i->decl_file,
1631 [ + - ]: 1 : q->line[0], &scope, addr, q);
1632 : : }
1633 : : else
1634 [ # # ]: 0 : query_inline_instance_info (*i, q);
1635 : : }
1636 : : }
1637 : 762 : }
1638 : :
1639 : :
1640 : : bool
1641 : 4600251 : inline_instance_info::operator<(const inline_instance_info& other) const
1642 : : {
1643 [ + + ]: 4600251 : if (entrypc != other.entrypc)
1644 : 4503032 : return entrypc < other.entrypc;
1645 : :
1646 [ + + ]: 97219 : if (decl_line != other.decl_line)
1647 : 97069 : return decl_line < other.decl_line;
1648 : :
1649 : 150 : int cmp = name.compare(other.name);
1650 [ + + ]: 150 : if (!cmp)
1651 : 44 : cmp = strcmp(decl_file, other.decl_file);
1652 : 4600251 : return cmp < 0;
1653 : : }
1654 : :
1655 : :
1656 : : static int
1657 : 213596 : query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
1658 : : {
1659 : 213596 : dwarf_query * q = static_cast<dwarf_query *>(arg);
1660 [ + + ][ - + ]: 213596 : assert (q->has_statement_str || q->has_function_str);
1661 [ + - ][ + - ]: 213596 : assert (!q->has_call && !q->has_return && !q->has_exported);
[ - + ]
1662 : :
1663 : : try
1664 : : {
1665 [ - + ]: 213596 : if (q->sess.verbose>2)
1666 [ # # ][ # # ]: 0 : clog << _F("selected inline instance of %s\n", q->dw.function_name.c_str());
[ # # ][ # # ]
1667 : :
1668 : : Dwarf_Addr entrypc;
1669 [ + - ][ + - ]: 213596 : if (q->dw.die_entrypc (die, &entrypc))
1670 : : {
1671 [ + - ]: 213596 : inline_instance_info inl;
1672 : 213596 : inl.die = *die;
1673 [ + - ]: 213596 : inl.name = q->dw.function_name;
1674 : 213596 : inl.entrypc = entrypc;
1675 [ + - ]: 213596 : q->dw.function_file (&inl.decl_file);
1676 [ + - ]: 213596 : q->dw.function_line (&inl.decl_line);
1677 : :
1678 : : // make sure that this inline hasn't already
1679 : : // been matched from a different CU
1680 [ + - ][ + + ]: 213596 : if (q->inline_dupes.insert(inl).second)
1681 [ + - ][ + - ]: 213596 : q->filtered_inlines.push_back(inl);
1682 : : }
1683 : 213596 : return DWARF_CB_OK;
1684 : : }
1685 [ # # ]: : catch (const semantic_error& e)
1686 : : {
1687 [ # # ]: : q->sess.print_error (e);
1688 : : return DWARF_CB_ABORT;
1689 : : }
1690 : : }
1691 : :
1692 : : static int
1693 : 712413 : query_dwarf_func (Dwarf_Die * func, base_query * bq)
1694 : : {
1695 : 712413 : dwarf_query * q = static_cast<dwarf_query *>(bq);
1696 [ + + ][ - + ]: 712413 : assert (q->has_statement_str || q->has_function_str);
1697 : :
1698 : : // weed out functions whose decl_file isn't one of
1699 : : // the source files that we actually care about
1700 [ + + ][ + + ]: 1449143 : if (q->spec_type != function_alone &&
[ + + ]
1701 [ + - ][ + + ]: 736730 : q->filtered_srcfiles.count(dwarf_decl_file(func)?:"") == 0)
[ + - ][ + - ]
[ + + ][ + - ]
[ + + ]
[ # # # # ]
1702 : 16330 : return DWARF_CB_OK;
1703 : :
1704 : : try
1705 : : {
1706 [ + - ]: 696083 : q->dw.focus_on_function (func);
1707 : :
1708 [ + - ][ - + ]: 696083 : if (!q->dw.function_scope_matches(q->scopes))
1709 : 0 : return DWARF_CB_OK;
1710 : :
1711 : : // make sure that this function address hasn't
1712 : : // already been matched under an aliased name
1713 : : Dwarf_Addr addr;
1714 [ + - ][ + + ]: 2067863 : if (!q->dw.func_is_inline() &&
[ + + ][ + + ]
[ + + ]
1715 [ + - ]: 440806 : dwarf_entrypc(func, &addr) == 0 &&
1716 [ + - ][ + + ]: 930974 : !q->alias_dupes.insert(addr).second)
[ # # ]
1717 : 9705 : return DWARF_CB_OK;
1718 : :
1719 [ + - ][ + + ]: 686378 : if (q->dw.func_is_inline () && (! q->has_call) && (! q->has_return) && (! q->has_exported))
[ + + ][ + + ]
[ + + ][ + + ]
1720 : : {
1721 [ - + ]: 111376 : if (q->sess.verbose>3)
1722 [ # # ][ # # ]: 0 : clog << _F("checking instances of inline %s\n", q->dw.function_name.c_str());
[ # # ][ # # ]
1723 [ + - ]: 111376 : q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, q);
1724 : : }
1725 [ + - ][ + + ]: 575002 : else if (q->dw.func_is_inline () && (q->has_return)) // PR 11553
[ + + ][ + + ]
1726 : : {
1727 [ + - ]: 53731 : q->inlined_non_returnable.insert (q->dw.function_name);
1728 : : }
1729 [ + - ][ + + ]: 521271 : else if (!q->dw.func_is_inline () && (! q->has_inline))
[ + + ][ + + ]
1730 : : {
1731 [ + + ][ + - ]: 357767 : if (q->has_exported && !q->dw.func_is_exported ())
[ + + ][ + + ]
1732 : 6 : return DWARF_CB_OK;
1733 [ - + ]: 357761 : if (q->sess.verbose>2)
1734 [ # # ][ # # ]: 0 : clog << _F("selected function %s\n", q->dw.function_name.c_str());
[ # # ][ # # ]
1735 : :
1736 [ + - ]: 357761 : func_info func;
1737 [ + - ]: 357761 : q->dw.function_die (&func.die);
1738 [ + - ]: 357761 : func.name = q->dw.function_name;
1739 [ + - ]: 357761 : q->dw.function_file (&func.decl_file);
1740 [ + - ]: 357761 : q->dw.function_line (&func.decl_line);
1741 : :
1742 : : Dwarf_Addr entrypc;
1743 [ + - ][ + + ]: 357761 : if (q->dw.function_entrypc (&entrypc))
1744 : : {
1745 : 193477 : func.entrypc = entrypc;
1746 [ + - ]: 193477 : q->filtered_functions.push_back (func);
1747 [ + - ]: 357761 : }
1748 : : /* else this function is fully inlined, just ignore it */
1749 : : }
1750 : 712413 : return DWARF_CB_OK;
1751 : : }
1752 [ # # ]: : catch (const semantic_error& e)
1753 : : {
1754 [ # # ]: : q->sess.print_error (e);
1755 : : return DWARF_CB_ABORT;
1756 : : }
1757 : : }
1758 : :
1759 : : static int
1760 : 191698 : query_cu (Dwarf_Die * cudie, void * arg)
1761 : : {
1762 : 191698 : dwarf_query * q = static_cast<dwarf_query *>(arg);
1763 [ + + ][ - + ]: 191698 : assert (q->has_statement_str || q->has_function_str);
1764 : :
1765 [ - + ]: 191698 : if (pending_interrupts) return DWARF_CB_ABORT;
1766 : :
1767 : : try
1768 : : {
1769 [ + - ]: 191698 : q->dw.focus_on_cu (cudie);
1770 : :
1771 : : if (false && q->sess.verbose>2)
1772 : : clog << _F("focused on CU '%s', in module '%s'\n",
1773 : : q->dw.cu_name().c_str(), q->dw.module_name.c_str());
1774 : :
1775 [ + - ]: 191698 : q->filtered_srcfiles.clear();
1776 [ + - ]: 191698 : q->filtered_functions.clear();
1777 [ + - ]: 191698 : q->filtered_inlines.clear();
1778 : :
1779 : : // In this path, we find "abstract functions", record
1780 : : // information about them, and then (depending on lineno
1781 : : // matching) possibly emit one or more of the function's
1782 : : // associated addresses. Unfortunately the control of this
1783 : : // cannot easily be turned inside out.
1784 : :
1785 [ + + ]: 191698 : if (q->spec_type != function_alone)
1786 : : {
1787 : : // If we have a pattern string with a filename, we need
1788 : : // to elaborate the srcfile mask in question first.
1789 [ + - ]: 121885 : q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
1790 : :
1791 : : // If we have a file pattern and *no* srcfile matches, there's
1792 : : // no need to look further into this CU, so skip.
1793 [ + - ][ + + ]: 121885 : if (q->filtered_srcfiles.empty())
1794 : 116874 : return DWARF_CB_OK;
1795 : : }
1796 : :
1797 : : // Pick up [entrypc, name, DIE] tuples for all the functions
1798 : : // matching the query, and fill in the prologue endings of them
1799 : : // all in a single pass.
1800 [ + - ]: 74824 : int rc = q->dw.iterate_over_functions (query_dwarf_func, q, q->function);
1801 [ - + ]: 74824 : if (rc != DWARF_CB_OK)
1802 : 0 : q->query_done = true;
1803 : :
1804 [ + + ][ + + ]: 74824 : if ((q->sess.prologue_searching || q->has_process) // PR 6871
[ + + ]
1805 : 65 : && !q->has_statement_str) // PR 2608
1806 [ + - ][ + + ]: 60 : if (! q->filtered_functions.empty())
1807 [ + - ]: 59 : q->dw.resolve_prologue_endings (q->filtered_functions);
1808 : : // NB: we could skip the resolve_prologue_endings() call here for has_return case (PR13200),
1809 : : // but don't have to. We can resolve the prologue, just not actually use it in query_addr().
1810 : :
1811 [ + + ]: 74824 : if (q->spec_type == function_file_and_line)
1812 : : {
1813 : : // .statement(...:NN) often gets mixed up with .function(...:NN)
1814 [ - + ]: 2847 : if (q->has_function_str)
1815 : 0 : q->sess.print_warning (_("For probing a particular line, use a "
1816 : : ".statement() probe, not .function()"),
1817 [ # # ][ # # ]: 1 : q->base_probe->tok);
[ # # ]
1818 : :
1819 : : // If we have a pattern string with target *line*, we
1820 : : // have to look at lines in all the matched srcfiles.
1821 : : void (* callback) (const dwarf_line_t&, void*) =
1822 [ - + ]: 2847 : q->has_label ? query_srcfile_label : query_srcfile_line;
1823 [ + - ][ + + ]: 559756 : for (set<string>::const_iterator i = q->filtered_srcfiles.begin();
1824 [ + - ]: 279878 : i != q->filtered_srcfiles.end(); ++i)
1825 : : q->dw.iterate_over_srcfile_lines (i->c_str(), q->line, q->has_statement_str,
1826 [ + - ][ + - ]: 277032 : q->line_type, callback, q->function, q);
[ + + ]
1827 : : }
1828 [ + + ]: 71977 : else if (q->has_label)
1829 : : {
1830 [ + - ][ + - ]: 16 : for (func_info_map_t::iterator i = q->filtered_functions.begin();
[ + + ]
1831 [ + - ]: 8 : i != q->filtered_functions.end(); ++i)
1832 : 5 : q->dw.iterate_over_labels (&i->die, q->label_val, i->name,
1833 [ + - ]: 5 : q, query_label);
1834 : :
1835 [ + - ][ + - ]: 8 : for (inline_instance_map_t::iterator i = q->filtered_inlines.begin();
[ + + ]
1836 [ + - ]: 4 : i != q->filtered_inlines.end(); ++i)
1837 : 1 : q->dw.iterate_over_labels (&i->die, q->label_val, i->name,
1838 [ + - ]: 1 : q, query_label);
1839 : : }
1840 : : else
1841 : : {
1842 : : // Otherwise, simply probe all resolved functions.
1843 [ + - ][ + - ]: 471518 : for (func_info_map_t::iterator i = q->filtered_functions.begin();
[ + + ]
1844 [ + - ]: 235759 : i != q->filtered_functions.end(); ++i)
1845 [ + - ]: 163785 : query_func_info (i->entrypc, *i, q);
1846 : :
1847 : : // And all inline instances (if we're not excluding inlines with ".call")
1848 [ + + ]: 71974 : if (! q->has_call)
1849 [ + - ][ + + ]: 490156 : for (inline_instance_map_t::iterator i
1850 [ + - ][ + - ]: 276691 : = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
1851 [ + - ]: 213465 : query_inline_instance_info (*i, q);
1852 : : }
1853 : 191698 : return DWARF_CB_OK;
1854 : : }
1855 [ - + ]: 2 : catch (const semantic_error& e)
1856 : : {
1857 [ - + ]: 1 : q->sess.print_error (e);
1858 : 1 : return DWARF_CB_ABORT;
1859 : : }
1860 : : }
1861 : :
1862 : :
1863 : : void
1864 : 45652 : dwarf_query::query_module_functions ()
1865 : : {
1866 : : try
1867 : : {
1868 [ + - ]: 45652 : filtered_srcfiles.clear();
1869 [ + - ]: 45652 : filtered_functions.clear();
1870 [ + - ]: 45652 : filtered_inlines.clear();
1871 : :
1872 : : // Collect all module functions so we know which CUs are interesting
1873 [ + - ]: 45652 : int rc = dw.iterate_single_function(query_dwarf_func, this, function);
1874 [ - + ]: 45652 : if (rc != DWARF_CB_OK)
1875 : : {
1876 : 0 : query_done = true;
1877 : 45652 : return;
1878 : : }
1879 : :
1880 [ + - ]: 45652 : set<void*> used_cus; // by cu->addr
1881 [ + - ]: 45652 : vector<Dwarf_Die> cus;
1882 : : Dwarf_Die cu_mem;
1883 : :
1884 [ + - ][ + - ]: 150634 : for (func_info_map_t::iterator i = filtered_functions.begin();
[ + + ]
1885 [ + - ]: 75317 : i != filtered_functions.end(); ++i)
1886 [ + - ][ + - ]: 29665 : if (dwarf_diecu(&i->die, &cu_mem, NULL, NULL) &&
[ + - ][ + - ]
[ + - ]
[ + - # # ]
1887 : : used_cus.insert(cu_mem.addr).second)
1888 [ + - ]: 29665 : cus.push_back(cu_mem);
1889 : :
1890 [ + - ][ + - ]: 91518 : for (inline_instance_map_t::iterator i = filtered_inlines.begin();
[ + + ]
1891 [ + - ]: 45759 : i != filtered_inlines.end(); ++i)
1892 [ + - ][ + - ]: 107 : if (dwarf_diecu(&i->die, &cu_mem, NULL, NULL) &&
[ + - ][ + + ]
[ + - ]
[ + + # # ]
1893 : : used_cus.insert(cu_mem.addr).second)
1894 [ + - ]: 19 : cus.push_back(cu_mem);
1895 : :
1896 : : // Reset the dupes since we didn't actually collect them the first time
1897 [ + - ]: 45652 : alias_dupes.clear();
1898 [ + - ]: 45652 : inline_dupes.clear();
1899 : :
1900 : : // Run the query again on the individual CUs
1901 [ + - ][ + - ]: 75336 : for (vector<Dwarf_Die>::iterator i = cus.begin(); i != cus.end(); ++i)
[ + - ][ + + ]
1902 [ + - ][ + - ]: 75336 : query_cu(&*i, this);
[ + - ]
1903 : : }
1904 [ # # ]: : catch (const semantic_error& e)
1905 : : {
1906 [ # # ]: : sess.print_error (e);
1907 : : }
1908 : : }
1909 : :
1910 : :
1911 : : static void
1912 : 79148 : validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
1913 : : {
1914 : : // Validate the machine code in this elf file against the
1915 : : // session machine. This is important, in case the wrong kind
1916 : : // of debuginfo is being automagically processed by elfutils.
1917 : : // While we can tell i686 apart from x86-64, unfortunately
1918 : : // we can't help confusing i586 vs i686 (both EM_386).
1919 : :
1920 : : Dwarf_Addr bias;
1921 : : // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
1922 : : // because dwfl_module_getelf can force costly section relocations
1923 : : // we don't really need, while either will do for this purpose.
1924 [ + - ][ + - ]: 79148 : Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
1925 [ + + ][ + - ]: 79148 : ?: dwfl_module_getelf (mod, &bias));
1926 : :
1927 : : GElf_Ehdr ehdr_mem;
1928 [ + - ]: 79148 : GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
1929 [ - + ][ # # ]: 79148 : if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
[ # # ][ # # ]
[ # # ]
1930 [ - + ]: 79148 : assert(em);
1931 : 79148 : int elf_machine = em->e_machine;
1932 : 79148 : const char* debug_filename = "";
1933 : 79148 : const char* main_filename = "";
1934 : : (void) dwfl_module_info (mod, NULL, NULL,
1935 : : NULL, NULL, NULL,
1936 : : & main_filename,
1937 [ + - ]: 79148 : & debug_filename);
1938 : 79148 : const string& sess_machine = q->sess.architecture;
1939 : :
1940 [ + - ]: 79148 : string expect_machine; // to match sess.machine (i.e., kernel machine)
1941 [ + - ]: 79148 : string expect_machine2;
1942 : :
1943 : : // NB: See also the 'uname -m' squashing done in main.cxx.
1944 [ - - - - : 79148 : switch (elf_machine)
- + - ]
1945 : : {
1946 : : // x86 and ppc are bi-architecture; a 64-bit kernel
1947 : : // can normally run either 32-bit or 64-bit *userspace*.
1948 : : case EM_386:
1949 [ # # ]: 0 : expect_machine = "i?86";
1950 [ # # ]: 0 : if (! q->has_process) break; // 32-bit kernel/module
1951 : : /* FALLSTHROUGH */
1952 : : case EM_X86_64:
1953 [ # # ]: 0 : expect_machine2 = "x86_64";
1954 : 0 : break;
1955 : : case EM_PPC:
1956 : : case EM_PPC64:
1957 [ # # ]: 0 : expect_machine = "powerpc";
1958 : 0 : break;
1959 [ # # ]: 0 : case EM_S390: expect_machine = "s390"; break;
1960 [ # # ]: 0 : case EM_IA_64: expect_machine = "ia64"; break;
1961 [ + - ]: 79148 : case EM_ARM: expect_machine = "arm*"; break;
1962 : : // XXX: fill in some more of these
1963 [ # # ]: 0 : default: expect_machine = "?"; break;
1964 : : }
1965 : :
1966 [ + - ]: 79148 : if (! debug_filename) debug_filename = main_filename;
1967 [ - + ]: 79148 : if (! debug_filename) debug_filename = name;
1968 : :
1969 [ + - ][ + - ]: 79148 : if (fnmatch (expect_machine.c_str(), sess_machine.c_str(), 0) != 0 &&
[ + - ][ - + ]
[ # # ][ - + ]
1970 [ # # ][ # # ]: 0 : fnmatch (expect_machine2.c_str(), sess_machine.c_str(), 0) != 0)
[ # # ]
1971 : : {
1972 [ # # ]: 0 : stringstream msg;
1973 [ # # ][ # # ]: 0 : msg << _F("ELF machine %s|%s (code %d) mismatch with target %s in '%s'",
[ # # ][ # # ]
[ # # ]
1974 : : expect_machine.c_str(), expect_machine2.c_str(), elf_machine,
1975 [ # # ]: 0 : sess_machine.c_str(), debug_filename);
1976 [ # # ][ # # ]: 0 : throw semantic_error(msg.str ());
1977 : : }
1978 : :
1979 [ + + ]: 79148 : if (q->sess.verbose>1)
1980 [ + - ][ + - ]: 7214 : clog << _F("focused on module '%s' = [%#" PRIx64 "-%#" PRIx64 ", bias %#" PRIx64
[ + - ][ + - ]
[ + - ]
1981 : : " file %s ELF machine %s|%s (code %d)\n",
1982 : : q->dw.module_name.c_str(), q->dw.module_start, q->dw.module_end,
1983 : : q->dw.module_bias, debug_filename, expect_machine.c_str(),
1984 [ + - ][ + - ]: 82755 : expect_machine2.c_str(), elf_machine);
[ + - ]
1985 : 79148 : }
1986 : :
1987 : :
1988 : :
1989 : : static Dwarf_Addr
1990 : 1515 : lookup_symbol_address (Dwfl_Module *m, const char* wanted)
1991 : : {
1992 : 1515 : int syments = dwfl_module_getsymtab(m);
1993 [ - + ]: 1515 : assert(syments);
1994 [ + + ]: 147493692 : for (int i = 1; i < syments; ++i)
1995 : : {
1996 : : GElf_Sym sym;
1997 [ + - ]: 147493548 : const char *name = dwfl_module_getsym(m, i, &sym, NULL);
1998 [ + - ][ + + ]: 147493548 : if (name != NULL && strcmp(name, wanted) == 0)
1999 : 1371 : return sym.st_value;
2000 : : }
2001 : :
2002 : 1515 : return 0;
2003 : : }
2004 : :
2005 : :
2006 : :
2007 : : static int
2008 : 85119 : query_module (Dwfl_Module *mod,
2009 : : void **,
2010 : : const char *name,
2011 : : Dwarf_Addr addr,
2012 : : void *arg)
2013 : : {
2014 : 85119 : base_query *q = static_cast<base_query *>(arg);
2015 : :
2016 : : try
2017 : : {
2018 [ + - ][ + - ]: 85119 : module_info* mi = q->sess.module_cache->cache[name];
[ + - ]
2019 [ + + ]: 85119 : if (mi == 0)
2020 : : {
2021 [ + - ][ + - ]: 4646 : mi = q->sess.module_cache->cache[name] = new module_info(name);
[ + - ][ + - ]
[ + - ]
2022 : :
2023 : 4646 : mi->mod = mod;
2024 : 4646 : mi->addr = addr;
2025 : :
2026 : 4646 : const char* debug_filename = "";
2027 : 4646 : const char* main_filename = "";
2028 : : (void) dwfl_module_info (mod, NULL, NULL,
2029 : : NULL, NULL, NULL,
2030 : : & main_filename,
2031 [ + - ]: 4646 : & debug_filename);
2032 : :
2033 [ + - ][ + - ]: 4646 : if (debug_filename || main_filename)
2034 : : {
2035 [ - + ][ + - ]: 4646 : mi->elf_path = debug_filename ?: main_filename;
2036 : : }
2037 [ # # ][ # # ]: 0 : else if (name == TOK_KERNEL)
2038 : : {
2039 : 4646 : mi->dwarf_status = info_absent;
2040 : : }
2041 : : }
2042 : : // OK, enough of that module_info caching business.
2043 : :
2044 [ + - ]: 85119 : q->dw.focus_on_module(mod, mi);
2045 : :
2046 : : // If we have enough information in the pattern to skip a module and
2047 : : // the module does not match that information, return early.
2048 [ + - ][ + + ]: 85119 : if (!q->dw.module_name_matches(q->module_val))
2049 [ - + ]: 5373 : return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
2050 : :
2051 : : // Don't allow module("*kernel*") type expressions to match the
2052 : : // elfutils module "kernel", which we refer to in the probe
2053 : : // point syntax exclusively as "kernel.*".
2054 [ + - ][ + + ]: 79746 : if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel)
[ + + ][ + + ]
2055 [ - + ]: 598 : return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
2056 : :
2057 [ + - ]: 79148 : if (mod)
2058 [ + - ]: 79148 : validate_module_elf(mod, name, q);
2059 : : else
2060 [ # # ]: 0 : assert(q->has_kernel); // and no vmlinux to examine
2061 : :
2062 [ - + ]: 79148 : if (q->sess.verbose>2)
2063 [ # # ][ # # ]: 0 : cerr << _F("focused on module '%s'\n", q->dw.module_name.c_str());
[ # # ][ # # ]
2064 : :
2065 : :
2066 : : // Collect a few kernel addresses. XXX: these belong better
2067 : : // to the sess.module_info["kernel"] struct.
2068 [ + - ][ + + ]: 79148 : if (q->dw.module_name == TOK_KERNEL)
2069 : : {
2070 [ + + ]: 48653 : if (! q->sess.sym_kprobes_text_start)
2071 [ + - ]: 457 : q->sess.sym_kprobes_text_start = lookup_symbol_address (mod, "__kprobes_text_start");
2072 [ + + ]: 48653 : if (! q->sess.sym_kprobes_text_end)
2073 [ + - ]: 457 : q->sess.sym_kprobes_text_end = lookup_symbol_address (mod, "__kprobes_text_end");
2074 [ + + ]: 48653 : if (! q->sess.sym_stext)
2075 [ + - ]: 457 : q->sess.sym_stext = lookup_symbol_address (mod, "_stext");
2076 : : }
2077 : :
2078 : : // We either have a wildcard or an unresolved library
2079 [ + + ][ + - ]: 79159 : if (q->has_library && (contains_glob_chars (q->path)
[ + + ][ - + ]
[ + + ]
2080 [ + - ]: 11 : || q->path.find('/') == string::npos))
2081 : : // handle .library(GLOB)
2082 [ + - ]: 1 : q->dw.iterate_over_libraries (&q->query_library_callback, q);
2083 : : // .plt is translated to .plt.statement(N). We only want to iterate for the
2084 : : // .plt case
2085 [ + + ][ + - ]: 79147 : else if (q->has_plt && ! q->has_statement)
2086 [ - + ]: 13 : q->dw.iterate_over_plt (q, &q->query_plt_callback);
2087 : : else
2088 : : // search the module for matches of the probe point.
2089 [ + - ]: 79134 : q->handle_query_module();
2090 : :
2091 : : // If we know that there will be no more matches, abort early.
2092 [ + - ][ + + ]: 79135 : if (q->dw.module_name_final_match(q->module_val) || pending_interrupts)
[ - + ][ + + ]
2093 : 55155 : return DWARF_CB_ABORT;
2094 : : else
2095 : 85119 : return DWARF_CB_OK;
2096 : : }
2097 [ - + ]: 26 : catch (const semantic_error& e)
2098 : : {
2099 [ - + ]: 13 : q->sess.print_error (e);
2100 : 13 : return DWARF_CB_ABORT;
2101 : : }
2102 : : }
2103 : :
2104 : :
2105 : : void
2106 : 11 : base_query::query_library_callback (void *q, const char *data)
2107 : : {
2108 : 11 : base_query *me = (base_query*)q;
2109 : 11 : me->query_library (data);
2110 : 11 : }
2111 : :
2112 : :
2113 : : void
2114 : 11 : query_one_library (const char *library, dwflpp & dw,
2115 : : const string user_lib, probe * base_probe, probe_point *base_loc,
2116 : : vector<derived_probe *> & results)
2117 : : {
2118 [ + - ][ + - ]: 11 : if (dw.function_name_matches_pattern(library, "*" + user_lib))
[ + - ][ + - ]
[ + - ][ + - ]
2119 : : {
2120 : : string library_path = find_executable (library, "", dw.sess.sysenv,
2121 [ + - ][ + - ]: 11 : "LD_LIBRARY_PATH");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
2122 [ + - ][ + - ]: 11 : probe_point* specific_loc = new probe_point(*base_loc);
2123 : 11 : specific_loc->optional = true;
2124 [ + - ]: 11 : vector<probe_point::component*> derived_comps;
2125 : :
2126 : 11 : vector<probe_point::component*>::iterator it;
2127 [ + - ][ + - ]: 88 : for (it = specific_loc->components.begin();
[ + + ]
2128 [ + - ]: 44 : it != specific_loc->components.end(); ++it)
2129 [ + - ][ + + ]: 33 : if ((*it)->functor == TOK_LIBRARY)
2130 : : derived_comps.push_back(new probe_point::component(TOK_LIBRARY,
2131 [ + - ][ + - ]: 11 : new literal_string(library_path)));
[ + - ][ + - ]
[ + - ]
2132 : : else
2133 [ + - ]: 22 : derived_comps.push_back(*it);
2134 [ + - ][ + - ]: 11 : probe_point* derived_loc = new probe_point(*specific_loc);
2135 [ + - ]: 11 : derived_loc->components = derived_comps;
2136 [ + - ]: 11 : probe *new_base = base_probe->create_alias(derived_loc, specific_loc);
2137 [ + - ]: 11 : derive_probes(dw.sess, new_base, results);
2138 [ - + ]: 11 : if (dw.sess.verbose > 2)
2139 [ # # ][ # # ]: 11 : clog << _("module=") << library_path;
[ + - ][ + - ]
2140 : : }
2141 : 11 : }
2142 : :
2143 : :
2144 : : void
2145 : 11 : dwarf_query::query_library (const char *library)
2146 : : {
2147 [ + - ]: 11 : query_one_library (library, dw, user_lib, base_probe, base_loc, results);
2148 : 11 : }
2149 : :
2150 [ # # ]: 0 : struct plt_expanding_visitor: public var_expanding_visitor
2151 : : {
2152 : 0 : plt_expanding_visitor(const string & entry):
2153 : 0 : entry (entry)
2154 : : {
2155 : 0 : }
2156 : : const string & entry;
2157 : :
2158 : : void visit_target_symbol (target_symbol* e);
2159 : : };
2160 : :
2161 : :
2162 : : void
2163 : 0 : base_query::query_plt_callback (void *q, const char *entry, size_t address)
2164 : : {
2165 : 0 : base_query *me = (base_query*)q;
2166 [ # # ][ # # ]: 0 : if (me->dw.function_name_matches_pattern (entry, me->plt_val))
[ # # ][ # # ]
2167 : 0 : me->query_plt (entry, address);
2168 : 0 : }
2169 : :
2170 : :
2171 : : void
2172 : 0 : query_one_plt (const char *entry, long addr, dwflpp & dw,
2173 : : probe * base_probe, probe_point *base_loc,
2174 : : vector<derived_probe *> & results)
2175 : : {
2176 [ # # ][ # # ]: 0 : probe_point* specific_loc = new probe_point(*base_loc);
2177 : 0 : specific_loc->optional = true;
2178 [ # # ]: 0 : vector<probe_point::component*> derived_comps;
2179 : :
2180 [ # # ]: 0 : if (dw.sess.verbose > 2)
2181 [ # # ][ # # ]: 0 : clog << _F("plt entry=%s\n", entry);
[ # # ]
2182 : :
2183 : : // query_module_symtab requires .plt to recognize that it can set the probe at
2184 : : // a plt entry so we convert process.plt to process.plt.statement
2185 : 0 : vector<probe_point::component*>::iterator it;
2186 [ # # ][ # # ]: 0 : for (it = specific_loc->components.begin();
[ # # ]
2187 [ # # ]: 0 : it != specific_loc->components.end(); ++it)
2188 [ # # ][ # # ]: 0 : if ((*it)->functor == TOK_PLT)
2189 : : {
2190 [ # # ]: 0 : derived_comps.push_back(*it);
2191 : : derived_comps.push_back(new probe_point::component(TOK_STATEMENT,
2192 [ # # ][ # # ]: 0 : new literal_number(addr)));
[ # # ][ # # ]
[ # # ]
2193 : : }
2194 : : else
2195 [ # # ]: 0 : derived_comps.push_back(*it);
2196 [ # # ][ # # ]: 0 : probe_point* derived_loc = new probe_point(*specific_loc);
2197 [ # # ]: 0 : derived_loc->components = derived_comps;
2198 [ # # ]: 0 : probe *new_base = base_probe->create_alias(derived_loc, specific_loc);
2199 [ # # ]: 0 : string e = string(entry);
2200 [ # # ]: 0 : plt_expanding_visitor pltv (e);
2201 [ # # ]: 0 : pltv.replace (new_base->body);
2202 [ # # ][ # # ]: 0 : derive_probes(dw.sess, new_base, results);
[ # # ][ # # ]
2203 : 0 : }
2204 : :
2205 : :
2206 : : void
2207 : 0 : dwarf_query::query_plt (const char *entry, size_t address)
2208 : : {
2209 : 0 : query_one_plt (entry, address, dw, base_probe, base_loc, results);
2210 : 0 : }
2211 : :
2212 : : // This would more naturally fit into elaborate.cxx:semantic_pass_symbols,
2213 : : // but the needed declaration for module_cache is not available there.
2214 : : // Nor for that matter in session.cxx. Only in this CU is that field ever
2215 : : // set (in query_module() above), so we clean it up here too.
2216 : : static void
2217 : 124278 : delete_session_module_cache (systemtap_session& s)
2218 : : {
2219 [ + + ]: 124278 : if (s.module_cache) {
2220 [ - + ]: 643 : if (s.verbose > 3)
2221 : 0 : clog << _("deleting module_cache") << endl;
2222 [ + - ]: 643 : delete s.module_cache;
2223 : 643 : s.module_cache = 0;
2224 : : }
2225 : 124278 : }
2226 : :
2227 : :
2228 [ + - ][ + - ]: 330173 : struct dwarf_var_expanding_visitor: public var_expanding_visitor
[ + - ][ - + ]
2229 : : {
2230 : : dwarf_query & q;
2231 : : Dwarf_Die *scope_die;
2232 : : Dwarf_Addr addr;
2233 : : block *add_block;
2234 : : block *add_call_probe; // synthesized from .return probes with saved $vars
2235 : : // NB: tids are not always collected in add_block & add_call_probe, because
2236 : : // gen_kretprobe_saved_return doesn't need them. Thus we need these extra
2237 : : // *_tid bools for gen_mapped_saved_return to tell what's there.
2238 : : bool add_block_tid, add_call_probe_tid;
2239 : : unsigned saved_longs, saved_strings; // data saved within kretprobes
2240 : : map<std::string, expression *> return_ts_map;
2241 : : vector<Dwarf_Die> scopes;
2242 : : // probe counter name -> pointer of associated probe
2243 : : std::set<derived_probe*> perf_counter_refs;
2244 : : bool visited;
2245 : :
2246 : 330173 : dwarf_var_expanding_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
2247 : : q(q), scope_die(sd), addr(a), add_block(NULL), add_call_probe(NULL),
2248 : : add_block_tid(false), add_call_probe_tid(false),
2249 [ + - ][ + - ]: 330173 : saved_longs(0), saved_strings(0), visited(false) {}
[ + - ]
2250 : : expression* gen_mapped_saved_return(expression* e, const string& name);
2251 : : expression* gen_kretprobe_saved_return(expression* e);
2252 : : void visit_target_symbol_saved_return (target_symbol* e);
2253 : : void visit_target_symbol_context (target_symbol* e);
2254 : : void visit_target_symbol (target_symbol* e);
2255 : : void visit_cast_op (cast_op* e);
2256 : : void visit_entry_op (entry_op* e);
2257 : : void visit_perf_op (perf_op* e);
2258 : : private:
2259 : : vector<Dwarf_Die>& getcuscope(target_symbol *e);
2260 : : vector<Dwarf_Die>& getscopes(target_symbol *e);
2261 : : };
2262 : :
2263 : :
2264 : : unsigned var_expanding_visitor::tick = 0;
2265 : :
2266 : :
2267 [ + - ][ + - ]: 354775 : var_expanding_visitor::var_expanding_visitor (): op()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
2268 : : {
2269 : : // FIXME: for the time being, by default we only support plain '$foo
2270 : : // = bar', not '+=' or any other op= variant. This is fixable, but a
2271 : : // bit ugly.
2272 : : //
2273 : : // If derived classes desire to add additional operator support, add
2274 : : // new operators to this list in the derived class constructor.
2275 [ + - ][ + - ]: 354775 : valid_ops.insert ("=");
[ + - ]
2276 : 354775 : }
2277 : :
2278 : :
2279 : : bool
2280 : 613658 : var_expanding_visitor::rewrite_lvalue(const token* tok, const std::string& eop,
2281 : : expression*& lvalue, expression*& rvalue)
2282 : : {
2283 : : // Our job would normally be to require() the left and right sides
2284 : : // into a new assignment. What we're doing is slightly trickier:
2285 : : // we're pushing a functioncall** onto a stack, and if our left
2286 : : // child sets the functioncall* for that value, we're going to
2287 : : // assume our left child was a target symbol -- transformed into a
2288 : : // set_target_foo(value) call, and it wants to take our right child
2289 : : // as the argument "value".
2290 : : //
2291 : : // This is why some people claim that languages with
2292 : : // constructor-decomposing case expressions have a leg up on
2293 : : // visitors.
2294 : :
2295 : 613658 : functioncall *fcall = NULL;
2296 : :
2297 : : // Let visit_target_symbol know what operator it should handle.
2298 : 613658 : const string* old_op = op;
2299 : 613658 : op = &eop;
2300 : :
2301 [ + - ]: 613658 : target_symbol_setter_functioncalls.push (&fcall);
2302 [ + + ]: 613658 : replace (lvalue);
2303 [ + - ]: 613657 : target_symbol_setter_functioncalls.pop ();
2304 [ + + ]: 613657 : replace (rvalue);
2305 : :
2306 : 613655 : op = old_op;
2307 : :
2308 [ + + ]: 613655 : if (fcall != NULL)
2309 : : {
2310 : : // Our left child is informing us that it was a target variable
2311 : : // and it has been replaced with a set_target_foo() function
2312 : : // call; we are going to provide that function call -- with the
2313 : : // right child spliced in as sole argument -- in place of
2314 : : // ourselves, in the var expansion we're in the middle of making.
2315 : :
2316 [ + - ][ + - ]: 56 : if (valid_ops.find (eop) == valid_ops.end ())
[ + + ]
2317 : : {
2318 : : // Build up a list of supported operators.
2319 [ + - ]: 4 : string ops;
2320 : 4 : std::set<string>::iterator i;
2321 : 4 : int valid_ops_size = 0;
2322 [ + - ][ + - ]: 8 : for (i = valid_ops.begin(); i != valid_ops.end(); i++)
[ + + ]
2323 : : {
2324 [ + - ][ + - ]: 4 : ops += " " + *i + ",";
[ + - ][ + - ]
[ + - ]
2325 : 4 : valid_ops_size++;
2326 : : }
2327 [ + - ][ + - ]: 4 : ops.resize(ops.size() - 1); // chop off the last ','
2328 : :
2329 : : // Throw the error.
2330 : 4 : throw semantic_error (_F(ngettext("Only the following assign operator is implemented on target variables: %s",
2331 : : "Only the following assign operators are implemented on target variables: %s",
2332 [ + - ][ + - ]: 11 : valid_ops_size), ops.c_str()), tok);
[ + - ]
2333 : :
2334 : : }
2335 : :
2336 [ - + ]: 52 : assert (lvalue == fcall);
2337 [ + - ]: 52 : if (rvalue)
2338 [ + - ]: 52 : fcall->args.push_back (rvalue);
2339 [ + - ]: 52 : provide (fcall);
2340 : 52 : return true;
2341 : : }
2342 : : else
2343 : 613651 : return false;
2344 : : }
2345 : :
2346 : :
2347 : : void
2348 : 519808 : var_expanding_visitor::visit_assignment (assignment* e)
2349 : : {
2350 [ + + ]: 519808 : if (!rewrite_lvalue (e->tok, e->op, e->left, e->right))
2351 : 519753 : provide (e);
2352 : 519805 : }
2353 : :
2354 : :
2355 : : void
2356 : 3562 : var_expanding_visitor::visit_pre_crement (pre_crement* e)
2357 : : {
2358 : 3562 : expression *dummy = NULL;
2359 [ + + ][ + - ]: 3562 : if (!rewrite_lvalue (e->tok, e->op, e->operand, dummy))
2360 [ + - ]: 3560 : provide (e);
2361 : 3562 : }
2362 : :
2363 : :
2364 : : void
2365 : 85807 : var_expanding_visitor::visit_post_crement (post_crement* e)
2366 : : {
2367 : 85807 : expression *dummy = NULL;
2368 [ + + ][ + - ]: 85807 : if (!rewrite_lvalue (e->tok, e->op, e->operand, dummy))
2369 [ + - ]: 85806 : provide (e);
2370 : 85807 : }
2371 : :
2372 : :
2373 : : void
2374 : 4481 : var_expanding_visitor::visit_delete_statement (delete_statement* s)
2375 : : {
2376 [ + - ]: 4481 : string fakeop = "delete";
2377 : 4481 : expression *dummy = NULL;
2378 [ + + ][ + - ]: 4481 : if (!rewrite_lvalue (s->tok, fakeop, s->value, dummy))
2379 [ + - ][ + - ]: 4481 : provide (s);
2380 : 4480 : }
2381 : :
2382 : :
2383 : : void
2384 : 6588 : var_expanding_visitor::visit_defined_op (defined_op* e)
2385 : : {
2386 : 6588 : bool resolved = true;
2387 : :
2388 : 6588 : defined_ops.push (e);
2389 : : try {
2390 : : // NB: provide<>/require<> are NOT typesafe. So even though a defined_op is
2391 : : // defined with a target_symbol* operand, a subsidiary call may attempt to
2392 : : // rewrite it to a general expression* instead, and require<> happily
2393 : : // casts to/from void*, causing possible memory corruption. We use
2394 : : // expression* here, being the general case of rewritten $variable.
2395 : 6588 : expression *foo1 = e->operand;
2396 [ + - ]: 6588 : foo1 = require (foo1);
2397 : :
2398 : : // NB: Formerly, we had some curious cases to consider here, depending on what
2399 : : // various visit_target_symbol() implementations do for successful or
2400 : : // erroneous resolutions. Some would signal a visit_target_symbol failure
2401 : : // with an exception, with a set flag within the target_symbol, or nothing
2402 : : // at all.
2403 : : //
2404 : : // Now, failures always have to be signalled with a
2405 : : // saved_conversion_error being chained to the target_symbol.
2406 : : // Successes have to result in an attempted rewrite of the
2407 : : // target_symbol (via provide()).
2408 : : //
2409 : : // Edna Mode: "no capes". fche: "no exceptions".
2410 : :
2411 : : // dwarf stuff: success: rewrites to a function; failure: retains target_symbol, sets saved_conversion_error
2412 : : //
2413 : : // sdt-kprobes sdt.h: success: string or functioncall; failure: semantic_error
2414 : : //
2415 : : // sdt-uprobes: success: string or no op; failure: no op; expect derived/synthetic
2416 : : // dwarf probe to take care of it.
2417 : : // But this is rather unhelpful. So we rig the sdt_var_expanding_visitor
2418 : : // to pass through @defined() to the synthetic dwarf probe.
2419 : : //
2420 : : // utrace: success: rewrites to function; failure: semantic_error
2421 : : //
2422 : : // procfs: success: rewrites to function; failure: semantic_error
2423 : :
2424 [ - + ]: 6588 : target_symbol* foo2 = dynamic_cast<target_symbol*> (foo1);
2425 [ + + ][ + + ]: 6588 : if (foo2 && foo2->saved_conversion_error) // failing
2426 : 2455 : resolved = false;
2427 [ + + ]: 4133 : else if (foo2) // unresolved but not marked failing
2428 : : {
2429 : : // There are some visitors that won't touch certain target_symbols,
2430 : : // e.g. dwarf_var_expanding_visitor won't resolve @cast. We should
2431 : : // leave it for now so some other visitor can have a chance.
2432 : 14 : e->operand = foo2;
2433 [ + - ]: 14 : provide (e);
2434 [ # # ]: 6588 : return;
2435 : : }
2436 : : else // resolved, rewritten to some other expression type
2437 : 4119 : resolved = true;
2438 : : } catch (const semantic_error& e) {
2439 : : assert (0); // should not happen
2440 : : }
2441 : 6574 : defined_ops.pop ();
2442 : :
2443 [ + + ][ + - ]: 6574 : literal_number* ln = new literal_number (resolved ? 1 : 0);
2444 : 6574 : ln->tok = e->tok;
2445 : 6574 : provide (ln);
2446 : : }
2447 : :
2448 : :
2449 : : struct dwarf_pretty_print
2450 : : {
2451 : 1581 : dwarf_pretty_print (dwflpp& dw, vector<Dwarf_Die>& scopes, Dwarf_Addr pc,
2452 : : const string& local, bool userspace_p,
2453 : : const target_symbol& e):
2454 : : dw(dw), local(local), scopes(scopes), pc(pc), pointer(NULL),
2455 [ + - ]: 1581 : userspace_p(userspace_p), deref_p(true)
2456 : : {
2457 [ + - ]: 1581 : init_ts (e);
2458 [ + - ]: 1581 : dw.type_die_for_local (scopes, pc, local, ts, &base_type);
2459 : 1581 : }
2460 : :
2461 : 0 : dwarf_pretty_print (dwflpp& dw, Dwarf_Die *scope_die, Dwarf_Addr pc,
2462 : : bool userspace_p, const target_symbol& e):
2463 : : dw(dw), scopes(1, *scope_die), pc(pc), pointer(NULL),
2464 [ # # ]: 0 : userspace_p(userspace_p), deref_p(true)
2465 : : {
2466 [ # # ]: 0 : init_ts (e);
2467 [ # # ]: 0 : dw.type_die_for_return (&scopes[0], pc, ts, &base_type);
2468 : 0 : }
2469 : :
2470 : 888 : dwarf_pretty_print (dwflpp& dw, Dwarf_Die *type_die, expression* pointer,
2471 : : bool deref_p, bool userspace_p, const target_symbol& e):
2472 : : dw(dw), pc(0), pointer(pointer), pointer_type(*type_die),
2473 [ + - ]: 888 : userspace_p(userspace_p), deref_p(deref_p)
2474 : : {
2475 [ + - ]: 888 : init_ts (e);
2476 [ + - ]: 888 : dw.type_die_for_pointer (type_die, ts, &base_type);
2477 : 888 : }
2478 : :
2479 : : functioncall* expand ();
2480 [ + - ][ + - ]: 2469 : ~dwarf_pretty_print () { delete ts; }
[ + - ]
2481 : :
2482 : : private:
2483 : : dwflpp& dw;
2484 : : target_symbol* ts;
2485 : : bool print_full;
2486 : : Dwarf_Die base_type;
2487 : :
2488 : : string local;
2489 : : vector<Dwarf_Die> scopes;
2490 : : Dwarf_Addr pc;
2491 : :
2492 : : expression* pointer;
2493 : : Dwarf_Die pointer_type;
2494 : :
2495 : : const bool userspace_p, deref_p;
2496 : :
2497 : : void recurse (Dwarf_Die* type, target_symbol* e,
2498 : : print_format* pf, bool top=false);
2499 : : void recurse_bitfield (Dwarf_Die* type, target_symbol* e,
2500 : : print_format* pf);
2501 : : void recurse_base (Dwarf_Die* type, target_symbol* e,
2502 : : print_format* pf);
2503 : : void recurse_array (Dwarf_Die* type, target_symbol* e,
2504 : : print_format* pf, bool top);
2505 : : void recurse_pointer (Dwarf_Die* type, target_symbol* e,
2506 : : print_format* pf, bool top);
2507 : : void recurse_struct (Dwarf_Die* type, target_symbol* e,
2508 : : print_format* pf, bool top);
2509 : : void recurse_struct_members (Dwarf_Die* type, target_symbol* e,
2510 : : print_format* pf, int& count);
2511 : : bool print_chars (Dwarf_Die* type, target_symbol* e, print_format* pf);
2512 : :
2513 : : void init_ts (const target_symbol& e);
2514 : : expression* deref (target_symbol* e);
2515 : : bool push_deref (print_format* pf, const string& fmt, target_symbol* e);
2516 : : };
2517 : :
2518 : :
2519 : : void
2520 : 2469 : dwarf_pretty_print::init_ts (const target_symbol& e)
2521 : : {
2522 : : // Work with a new target_symbol so we can modify arguments
2523 [ + - ]: 2469 : ts = new target_symbol (e);
2524 : :
2525 [ - + ]: 2469 : if (ts->addressof)
2526 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of pretty-printed variable"), ts->tok);
2527 : :
2528 [ + - - + ]: 4938 : if (ts->components.empty() ||
[ - + ]
2529 : 2469 : ts->components.back().type != target_symbol::comp_pretty_print)
2530 [ # # ][ # # ]: 0 : throw semantic_error(_("invalid target_symbol for pretty-print"), ts->tok);
2531 : 2469 : print_full = ts->components.back().member.length() > 1;
2532 : 2469 : ts->components.pop_back();
2533 : 2469 : }
2534 : :
2535 : :
2536 : : functioncall*
2537 : 2469 : dwarf_pretty_print::expand ()
2538 : : {
2539 : : static unsigned tick = 0;
2540 : :
2541 : : // function pretty_print_X([pointer], [arg1, arg2, ...]) {
2542 : : // try {
2543 : : // return sprintf("{.foo=...}", (ts)->foo, ...)
2544 : : // } catch {
2545 : : // return "ERROR"
2546 : : // }
2547 : : // }
2548 : :
2549 : : // Create the function decl and call.
2550 : :
2551 [ + - ]: 2469 : functiondecl *fdecl = new functiondecl;
2552 : 2469 : fdecl->tok = ts->tok;
2553 : 2469 : fdecl->synthetic = true;
2554 [ + - ][ + - ]: 2469 : fdecl->name = "_dwarf_pretty_print_" + lex_cast(tick++);
[ + - ][ + - ]
[ + - ]
2555 : 2469 : fdecl->type = pe_string;
2556 : :
2557 [ + - ]: 2469 : functioncall* fcall = new functioncall;
2558 : 2469 : fcall->tok = ts->tok;
2559 : 2469 : fcall->function = fdecl->name;
2560 : 2469 : fcall->type = pe_string;
2561 : :
2562 : : // If there's a <pointer>, replace it with a new var and make that
2563 : : // the first function argument.
2564 [ + + ]: 2469 : if (pointer)
2565 : : {
2566 [ + - ][ + - ]: 888 : vardecl *v = new vardecl;
2567 : 888 : v->type = pe_long;
2568 [ + - ]: 888 : v->name = "pointer";
2569 : 888 : v->tok = ts->tok;
2570 [ + - ]: 888 : fdecl->formal_args.push_back (v);
2571 [ + - ]: 888 : fcall->args.push_back (pointer);
2572 : :
2573 [ + - ][ + - ]: 888 : symbol* sym = new symbol;
2574 : 888 : sym->tok = ts->tok;
2575 [ + - ]: 888 : sym->name = v->name;
2576 : 888 : pointer = sym;
2577 : : }
2578 : :
2579 : : // For each expression argument, replace it with a function argument.
2580 [ + + ]: 2553 : for (unsigned i = 0; i < ts->components.size(); ++i)
2581 [ + + ]: 84 : if (ts->components[i].type == target_symbol::comp_expression_array_index)
2582 : : {
2583 [ + - ][ + - ]: 14 : vardecl *v = new vardecl;
2584 : 14 : v->type = pe_long;
2585 [ + - ][ + - ]: 14 : v->name = "index" + lex_cast(i);
[ + - ][ + - ]
[ + - ]
2586 : 14 : v->tok = ts->tok;
2587 [ + - ]: 14 : fdecl->formal_args.push_back (v);
2588 [ + - ]: 14 : fcall->args.push_back (ts->components[i].expr_index);
2589 : :
2590 [ + - ][ + - ]: 14 : symbol* sym = new symbol;
2591 : 14 : sym->tok = ts->tok;
2592 [ + - ]: 14 : sym->name = v->name;
2593 : 14 : ts->components[i].expr_index = sym;
2594 : : }
2595 : :
2596 : : // Create the return sprintf.
2597 [ + - ]: 2469 : token* pf_tok = new token(*ts->tok);
2598 : 2469 : pf_tok->content = "sprintf";
2599 : 2469 : print_format* pf = print_format::create(pf_tok);
2600 [ + - ]: 2469 : return_statement* rs = new return_statement;
2601 : 2469 : rs->tok = ts->tok;
2602 : 2469 : rs->value = pf;
2603 : :
2604 : : // Recurse into the actual values.
2605 : 2469 : recurse (&base_type, ts, pf, true);
2606 [ + - ]: 2469 : pf->components = print_format::string_to_components(pf->raw_components);
2607 : :
2608 : : // Create the try-catch net
2609 [ + - ]: 2469 : try_block* tb = new try_block;
2610 : 2469 : tb->tok = ts->tok;
2611 : 2469 : tb->try_block = rs;
2612 : 2469 : tb->catch_error_var = 0;
2613 [ + - ]: 2469 : return_statement* rs2 = new return_statement;
2614 : 2469 : rs2->tok = ts->tok;
2615 [ + - ][ + - ]: 2469 : rs2->value = new literal_string ("ERROR");
[ + - ][ + - ]
2616 : 2469 : rs2->value->tok = ts->tok;
2617 : 2469 : tb->catch_block = rs2;
2618 : 2469 : fdecl->body = tb;
2619 : :
2620 : 2469 : fdecl->join (dw.sess);
2621 : 2469 : return fcall;
2622 : : }
2623 : :
2624 : :
2625 : : void
2626 : 47399 : dwarf_pretty_print::recurse (Dwarf_Die* start_type, target_symbol* e,
2627 : : print_format* pf, bool top)
2628 : : {
2629 : : Dwarf_Die type;
2630 [ + - ]: 47399 : dw.resolve_unqualified_inner_typedie (start_type, &type, e);
2631 : :
2632 [ + - ][ - + : 47399 : switch (dwarf_tag(&type))
+ + + + ]
2633 : : {
2634 : : default:
2635 : : // XXX need a warning?
2636 : : // throw semantic_error ("unsupported type (tag " + lex_cast(dwarf_tag(&type))
2637 : : // + ") for " + dwarf_type_name(&type), e->tok);
2638 [ # # ]: 0 : pf->raw_components.append("?");
2639 : 0 : break;
2640 : :
2641 : : case DW_TAG_enumeration_type:
2642 : : case DW_TAG_base_type:
2643 [ + - ]: 19373 : recurse_base (&type, e, pf);
2644 : 19373 : break;
2645 : :
2646 : : case DW_TAG_array_type:
2647 [ + - ]: 416 : recurse_array (&type, e, pf, top);
2648 : 416 : break;
2649 : :
2650 : : case DW_TAG_pointer_type:
2651 : : case DW_TAG_reference_type:
2652 : : case DW_TAG_rvalue_reference_type:
2653 [ + - ]: 14063 : recurse_pointer (&type, e, pf, top);
2654 : 14063 : break;
2655 : :
2656 : : case DW_TAG_subroutine_type:
2657 [ + - ][ + - ]: 46 : push_deref (pf, "<function>:%p", e);
[ + - ]
2658 : 46 : break;
2659 : :
2660 : : case DW_TAG_union_type:
2661 : : case DW_TAG_structure_type:
2662 : : case DW_TAG_class_type:
2663 [ + - ]: 13501 : recurse_struct (&type, e, pf, top);
2664 : 13501 : break;
2665 : : }
2666 : 47399 : }
2667 : :
2668 : :
2669 : : // Bit fields are handled as a special-case combination of recurse() and
2670 : : // recurse_base(), only called from recurse_struct_members(). The main
2671 : : // difference is that the value is always printed numerically, even if the
2672 : : // underlying type is a char.
2673 : : void
2674 : 421 : dwarf_pretty_print::recurse_bitfield (Dwarf_Die* start_type, target_symbol* e,
2675 : : print_format* pf)
2676 : : {
2677 : : Dwarf_Die type;
2678 [ + - ]: 421 : dw.resolve_unqualified_inner_typedie (start_type, &type, e);
2679 : :
2680 [ + - ]: 421 : int tag = dwarf_tag(&type);
2681 [ - + ][ # # ]: 421 : if (tag != DW_TAG_base_type && tag != DW_TAG_enumeration_type)
2682 : : {
2683 : : // XXX need a warning?
2684 : : // throw semantic_error ("unsupported bitfield type (tag " + lex_cast(tag)
2685 : : // + ") for " + dwarf_type_name(&type), e->tok);
2686 [ # # ]: 0 : pf->raw_components.append("?");
2687 : 421 : return;
2688 : : }
2689 : :
2690 : : Dwarf_Attribute attr;
2691 : 421 : Dwarf_Word encoding = (Dwarf_Word) -1;
2692 : : dwarf_formudata (dwarf_attr_integrate (&type, DW_AT_encoding, &attr),
2693 [ + - ][ + - ]: 421 : &encoding);
2694 [ - + + ]: 421 : switch (encoding)
2695 : : {
2696 : : case DW_ATE_float:
2697 : : case DW_ATE_complex_float:
2698 : : // XXX need a warning?
2699 : : // throw semantic_error ("unsupported bitfield type (encoding " + lex_cast(encoding)
2700 : : // + ") for " + dwarf_type_name(&type), e->tok);
2701 [ # # ]: 0 : pf->raw_components.append("?");
2702 : 0 : break;
2703 : :
2704 : : case DW_ATE_unsigned:
2705 : : case DW_ATE_unsigned_char:
2706 [ + - ][ + - ]: 391 : push_deref (pf, "%u", e);
[ + - ]
2707 : 391 : break;
2708 : :
2709 : : case DW_ATE_signed:
2710 : : case DW_ATE_signed_char:
2711 : : default:
2712 [ + - ][ + - ]: 30 : push_deref (pf, "%i", e);
[ + - ]
2713 : 421 : break;
2714 : : }
2715 : : }
2716 : :
2717 : :
2718 : : void
2719 : 19373 : dwarf_pretty_print::recurse_base (Dwarf_Die* type, target_symbol* e,
2720 : : print_format* pf)
2721 : : {
2722 : : Dwarf_Attribute attr;
2723 : 19373 : Dwarf_Word encoding = (Dwarf_Word) -1;
2724 : : dwarf_formudata (dwarf_attr_integrate (type, DW_AT_encoding, &attr),
2725 [ + - ][ + - ]: 19373 : &encoding);
2726 [ - + + + ]: 19373 : switch (encoding)
2727 : : {
2728 : : case DW_ATE_float:
2729 : : case DW_ATE_complex_float:
2730 : : // XXX need a warning?
2731 : : // throw semantic_error ("unsupported type (encoding " + lex_cast(encoding)
2732 : : // + ") for " + dwarf_type_name(type), e->tok);
2733 [ # # ]: 0 : pf->raw_components.append("?");
2734 : 0 : break;
2735 : :
2736 : : case DW_ATE_UTF: // XXX need to add unicode to _stp_vsprint_char
2737 : : case DW_ATE_signed_char:
2738 : : case DW_ATE_unsigned_char:
2739 : : // Use escapes to make sure that non-printable characters
2740 : : // don't interrupt our stream (especially '\0' values).
2741 [ + - ][ + - ]: 215 : push_deref (pf, "'%#c'", e);
[ + - ]
2742 : 215 : break;
2743 : :
2744 : : case DW_ATE_unsigned:
2745 [ + - ][ + - ]: 13015 : push_deref (pf, "%u", e);
[ + - ]
2746 : 13015 : break;
2747 : :
2748 : : case DW_ATE_signed:
2749 : : default:
2750 [ + - ][ + - ]: 6143 : push_deref (pf, "%i", e);
[ + - ]
2751 : 6143 : break;
2752 : : }
2753 : 19373 : }
2754 : :
2755 : :
2756 : : void
2757 : 416 : dwarf_pretty_print::recurse_array (Dwarf_Die* type, target_symbol* e,
2758 : : print_format* pf, bool top)
2759 : : {
2760 [ + + ][ + + ]: 416 : if (!top && !print_full)
2761 : : {
2762 [ + - ]: 2 : pf->raw_components.append("[...]");
2763 : : return;
2764 : : }
2765 : :
2766 : : Dwarf_Die childtype;
2767 [ + - ]: 414 : dwarf_attr_die (type, DW_AT_type, &childtype);
2768 : :
2769 [ + - ][ + + ]: 414 : if (print_chars (&childtype, e, pf))
2770 : : return;
2771 : :
2772 [ + - ]: 217 : pf->raw_components.append("[");
2773 : :
2774 : : // We print the array up to the first 5 elements.
2775 : : // XXX how can we determine the array size?
2776 : : // ... for now, just print the first element
2777 : : // NB: limit to 32 args; see PR10750 and c_unparser::visit_print_format.
2778 : 217 : unsigned i, size = 1;
2779 [ + + ][ + - ]: 434 : for (i=0; i < size && i < 5 && pf->args.size() < 32; ++i)
[ + - ][ + + ]
2780 : : {
2781 [ - + ]: 217 : if (i > 0)
2782 [ # # ]: 0 : pf->raw_components.append(", ");
2783 [ + - ][ + - ]: 217 : target_symbol* e2 = new target_symbol(*e);
2784 [ + - ][ + - ]: 217 : e2->components.push_back (target_symbol::component(e->tok, i));
[ + - ]
2785 [ + - ]: 217 : recurse (&childtype, e2, pf);
2786 : : }
2787 : : if (i < size || 1/*XXX until real size is known */)
2788 [ + - ]: 217 : pf->raw_components.append(", ...");
2789 [ + - ]: 416 : pf->raw_components.append("]");
2790 : : }
2791 : :
2792 : :
2793 : : void
2794 : 14063 : dwarf_pretty_print::recurse_pointer (Dwarf_Die* type, target_symbol* e,
2795 : : print_format* pf, bool top)
2796 : : {
2797 : : // We chase to top-level pointers, but leave the rest alone
2798 : 14063 : bool void_p = true;
2799 : : Dwarf_Die pointee;
2800 [ + - ][ + + ]: 14063 : if (dwarf_attr_die (type, DW_AT_type, &pointee))
2801 : : {
2802 : : try
2803 : : {
2804 [ + + ]: 12005 : dw.resolve_unqualified_inner_typedie (&pointee, &pointee, e);
2805 : 11980 : void_p = false;
2806 : : }
2807 : 25 : catch (const semantic_error&) {}
2808 : : }
2809 : :
2810 [ + + ]: 14063 : if (!void_p)
2811 : : {
2812 [ + - ][ + + ]: 11980 : if (print_chars (&pointee, e, pf))
2813 : : return;
2814 : :
2815 [ + + ]: 11388 : if (top)
2816 : : {
2817 [ + - ]: 1159 : recurse (&pointee, e, pf, top);
2818 : : return;
2819 : : }
2820 : : }
2821 : :
2822 [ + - ][ + - ]: 14088 : push_deref (pf, "%p", e);
[ + - ][ - + ]
2823 : : }
2824 : :
2825 : :
2826 : : void
2827 : 13501 : dwarf_pretty_print::recurse_struct (Dwarf_Die* type, target_symbol* e,
2828 : : print_format* pf, bool top)
2829 : : {
2830 [ + - ][ + + ]: 13501 : if (dwarf_hasattr(type, DW_AT_declaration))
2831 : : {
2832 [ + - ]: 103 : Dwarf_Die *resolved = dw.declaration_resolve(type);
2833 [ + + ]: 103 : if (!resolved)
2834 : : {
2835 : : // could be an error, but for now just stub it
2836 : : // throw semantic_error ("unresolved " + dwarf_type_name(type), e->tok);
2837 [ + - ]: 80 : pf->raw_components.append("{...}");
2838 : 13501 : return;
2839 : : }
2840 : 23 : type = resolved;
2841 : : }
2842 : :
2843 : 13421 : int count = 0;
2844 [ + - ]: 13421 : pf->raw_components.append("{");
2845 [ + + ][ + + ]: 13421 : if (top || print_full)
2846 [ + - ]: 13318 : recurse_struct_members (type, e, pf, count);
2847 : : else
2848 [ + - ]: 103 : pf->raw_components.append("...");
2849 [ + - ]: 13501 : pf->raw_components.append("}");
2850 : : }
2851 : :
2852 : :
2853 : : void
2854 : 13318 : dwarf_pretty_print::recurse_struct_members (Dwarf_Die* type, target_symbol* e,
2855 : : print_format* pf, int& count)
2856 : : {
2857 : : /* With inheritance, a subclass may mask member names of parent classes, so
2858 : : * our search among the inheritance tree must be breadth-first rather than
2859 : : * depth-first (recursive). The type die is still our starting point. When
2860 : : * we encounter a masked name, just skip it. */
2861 [ + - ]: 13318 : set<string> dupes;
2862 [ + - ]: 13318 : deque<Dwarf_Die> inheritees(1, *type);
2863 [ + - ][ + - ]: 26636 : for (; !inheritees.empty(); inheritees.pop_front())
[ + + ]
2864 : : {
2865 : : Dwarf_Die child, childtype, import;
2866 [ + - ][ + - ]: 13318 : if (dwarf_child (&inheritees.front(), &child) == 0)
[ + + ]
2867 [ + + ]: 45342 : do
2868 : : {
2869 : 45342 : target_symbol* e2 = e;
2870 : :
2871 : : // skip static members
2872 [ + - ][ + + ]: 45342 : if (dwarf_hasattr(&child, DW_AT_declaration))
2873 : 30 : continue;
2874 : :
2875 [ + - ]: 45312 : int tag = dwarf_tag (&child);
2876 : :
2877 : : /* Pretend imported units contain members by recursing into
2878 : : struct_member printing with the same count. */
2879 [ - + ][ # # ]: 45312 : if (tag == DW_TAG_imported_unit
[ - + ]
2880 [ # # ]: 0 : && dwarf_attr_die (&child, DW_AT_import, &import))
2881 [ # # ]: 0 : recurse_struct_members (&import, e2, pf, count);
2882 : :
2883 [ - + ][ # # ]: 45312 : if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
2884 : 0 : continue;
2885 : :
2886 [ + - ]: 45312 : dwarf_attr_die (&child, DW_AT_type, &childtype);
2887 : :
2888 [ - + ]: 45312 : if (tag == DW_TAG_inheritance)
2889 : : {
2890 [ # # ]: 0 : inheritees.push_back(childtype);
2891 : 0 : continue;
2892 : : }
2893 : :
2894 [ + - ]: 45312 : int childtag = dwarf_tag (&childtype);
2895 [ + - ]: 45312 : const char *member = dwarf_diename (&child);
2896 : :
2897 : : // "_vptr.foo" members are C++ virtual function tables,
2898 : : // which (generally?) aren't interesting for users.
2899 [ + + ][ + - ]: 45312 : if (member && startswith(member, "_vptr."))
[ + - ][ - + ]
[ + + ][ + - ]
[ + + ][ - +
# # # # ]
2900 : 0 : continue;
2901 : :
2902 : : // skip inheritance-masked duplicates
2903 [ + + ][ + - ]: 45312 : if (member && !dupes.insert(member).second)
[ + - ][ - + ]
[ + + ][ + + ]
[ + - ][ + + ]
[ - + # #
# # # # ]
2904 : 0 : continue;
2905 : :
2906 [ + + ]: 45312 : if (++count > 1)
2907 [ + - ]: 32006 : pf->raw_components.append(", ");
2908 : :
2909 : : // NB: limit to 32 args; see PR10750 and c_unparser::visit_print_format.
2910 [ + + ]: 45312 : if (pf->args.size() >= 32)
2911 : : {
2912 [ + - ]: 1337 : pf->raw_components.append("...");
2913 : 1337 : break;
2914 : : }
2915 : :
2916 [ + + ]: 43975 : if (member)
2917 : : {
2918 [ + - ]: 42378 : pf->raw_components.append(".");
2919 [ + - ]: 42378 : pf->raw_components.append(member);
2920 : :
2921 [ + - ][ + - ]: 42378 : e2 = new target_symbol(*e);
2922 [ + - ][ + - ]: 42378 : e2->components.push_back (target_symbol::component(e->tok, member));
[ + - ][ + - ]
[ + - ]
2923 : : }
2924 [ + + ]: 1597 : else if (childtag == DW_TAG_union_type)
2925 [ + - ]: 1451 : pf->raw_components.append("<union>");
2926 [ + - ]: 146 : else if (childtag == DW_TAG_structure_type)
2927 [ + - ]: 146 : pf->raw_components.append("<class>");
2928 [ # # ]: 0 : else if (childtag == DW_TAG_class_type)
2929 [ # # ]: 0 : pf->raw_components.append("<struct>");
2930 [ + - ]: 43975 : pf->raw_components.append("=");
2931 : :
2932 [ + - ][ + + ]: 43975 : if (dwarf_hasattr_integrate (&child, DW_AT_bit_offset))
2933 [ + - ]: 421 : recurse_bitfield (&childtype, e2, pf);
2934 : : else
2935 [ + - ]: 43554 : recurse (&childtype, e2, pf);
2936 : : }
2937 [ + - ]: 44005 : while (dwarf_siblingof (&child, &child) == 0);
2938 [ + - ][ + - ]: 13318 : }
2939 : 13318 : }
2940 : :
2941 : :
2942 : : bool
2943 : 12394 : dwarf_pretty_print::print_chars (Dwarf_Die* start_type, target_symbol* e,
2944 : : print_format* pf)
2945 : : {
2946 : : Dwarf_Die type;
2947 [ + - ]: 12394 : dw.resolve_unqualified_inner_typedie (start_type, &type, e);
2948 : :
2949 : : Dwarf_Attribute attr;
2950 : 12394 : Dwarf_Word encoding = (Dwarf_Word) -1;
2951 : : dwarf_formudata (dwarf_attr_integrate (&type, DW_AT_encoding, &attr),
2952 [ + - ][ + - ]: 12394 : &encoding);
2953 [ + + ]: 12394 : switch (encoding)
2954 : : {
2955 : : case DW_ATE_UTF:
2956 : : case DW_ATE_signed_char:
2957 : : case DW_ATE_unsigned_char:
2958 : 789 : break;
2959 : : default:
2960 : 11605 : return false;
2961 : : }
2962 : :
2963 [ + + ][ + - ]: 789 : string function = userspace_p ? "user_string2" : "kernel_string2";
2964 : 789 : Dwarf_Word size = (Dwarf_Word) -1;
2965 [ + - ][ + - ]: 789 : dwarf_formudata (dwarf_attr_integrate (&type, DW_AT_byte_size, &attr), &size);
2966 [ + + + - ]: 789 : switch (size)
2967 : : {
2968 : : case 1:
2969 : 787 : break;
2970 : : case 2:
2971 [ + - ]: 1 : function += "_utf16";
2972 : 1 : break;
2973 : : case 4:
2974 [ + - ]: 1 : function += "_utf32";
2975 : 1 : break;
2976 : : default:
2977 : 0 : return false;
2978 : : }
2979 : :
2980 [ + - ][ + - ]: 789 : if (push_deref (pf, "\"%s\"", e))
[ + - ][ + - ]
2981 : : {
2982 : : // steal the last arg for a string access
2983 [ + - ][ - + ]: 789 : assert (!pf->args.empty());
2984 [ + - ][ + - ]: 789 : functioncall* fcall = new functioncall;
2985 : 789 : fcall->tok = e->tok;
2986 [ + - ]: 789 : fcall->function = function;
2987 [ + - ][ + - ]: 789 : fcall->args.push_back (pf->args.back());
2988 [ + - ][ + - ]: 789 : expression *err_msg = new literal_string ("<unknown>");
[ + - ][ + - ]
2989 : 789 : err_msg->tok = e->tok;
2990 [ + - ]: 789 : fcall->args.push_back (err_msg);
2991 [ + - ]: 789 : pf->args.back() = fcall;
2992 : : }
2993 [ + - ]: 12394 : return true;
2994 : : }
2995 : :
2996 : : // PR10601: adapt to kernel-vs-userspace loc2c-runtime
2997 [ + - ][ + - ]: 2414 : static const string EMBEDDED_FETCH_DEREF_KERNEL = string("\n")
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
2998 : : + "#define fetch_register k_fetch_register\n"
2999 : : + "#define store_register k_store_register\n"
3000 : : + "#define deref kderef\n"
3001 : : + "#define store_deref store_kderef\n";
3002 : :
3003 [ + - ][ + - ]: 2414 : static const string EMBEDDED_FETCH_DEREF_USER = string("\n")
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3004 : : + "#define fetch_register u_fetch_register\n"
3005 : : + "#define store_register u_store_register\n"
3006 : : + "#define deref uderef\n"
3007 : : + "#define store_deref store_uderef\n";
3008 : :
3009 : : #define EMBEDDED_FETCH_DEREF(U) \
3010 : : (U ? EMBEDDED_FETCH_DEREF_USER : EMBEDDED_FETCH_DEREF_KERNEL)
3011 : :
3012 [ + - ][ + - ]: 2414 : static const string EMBEDDED_FETCH_DEREF_DONE = string("\n")
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3013 : : + "#undef fetch_register\n"
3014 : : + "#undef store_register\n"
3015 : : + "#undef deref\n"
3016 : : + "#undef store_deref\n";
3017 : :
3018 : : static functioncall*
3019 : 183124 : synthetic_embedded_deref_call(systemtap_session& session,
3020 : : const string& function_name,
3021 : : const string& function_code,
3022 : : exp_type function_type,
3023 : : bool userspace_p,
3024 : : bool lvalue_p,
3025 : : target_symbol* e,
3026 : : expression* pointer=NULL)
3027 : : {
3028 : : // Synthesize a functiondecl for the given embedded code string.
3029 [ + - ]: 183124 : functiondecl *fdecl = new functiondecl;
3030 : 183124 : fdecl->synthetic = true;
3031 : 183124 : fdecl->tok = e->tok;
3032 : 183124 : fdecl->name = function_name;
3033 : 183124 : fdecl->type = function_type;
3034 : :
3035 [ + - ]: 183124 : embeddedcode *ec = new embeddedcode;
3036 : 183124 : ec->tok = e->tok;
3037 : 183124 : ec->code += "/* unprivileged */";
3038 [ + + ]: 183124 : if (! lvalue_p)
3039 : 183106 : ec->code += "/* pure */";
3040 [ + + ]: 183124 : ec->code += EMBEDDED_FETCH_DEREF(userspace_p);
3041 : 183124 : ec->code += function_code;
3042 : 183124 : ec->code += EMBEDDED_FETCH_DEREF_DONE;
3043 : 183124 : fdecl->body = ec;
3044 : :
3045 : : // Synthesize a functioncall.
3046 [ + - ]: 183124 : functioncall* fcall = new functioncall;
3047 : 183124 : fcall->tok = e->tok;
3048 : 183124 : fcall->function = fdecl->name;
3049 : 183124 : fcall->type = fdecl->type;
3050 : :
3051 : : // If this code snippet uses a precomputed pointer,
3052 : : // pass that as the first argument.
3053 [ + + ]: 183124 : if (pointer)
3054 : : {
3055 [ + - ][ + - ]: 16112 : vardecl *v = new vardecl;
3056 : 16112 : v->type = pe_long;
3057 [ + - ]: 16112 : v->name = "pointer";
3058 : 16112 : v->tok = e->tok;
3059 [ + - ]: 16112 : fdecl->formal_args.push_back(v);
3060 [ + - ]: 16112 : fcall->args.push_back(pointer);
3061 : : }
3062 : :
3063 : : // Any non-literal indexes need to be passed as arguments too.
3064 [ + + ]: 257079 : for (unsigned i = 0; i < e->components.size(); ++i)
3065 [ + + ]: 73955 : if (e->components[i].type == target_symbol::comp_expression_array_index)
3066 : : {
3067 [ + - ][ + - ]: 42 : vardecl *v = new vardecl;
3068 : 42 : v->type = pe_long;
3069 [ + - ][ + - ]: 42 : v->name = "index" + lex_cast(i);
[ + - ][ + - ]
[ + - ]
3070 : 42 : v->tok = e->tok;
3071 [ + - ]: 42 : fdecl->formal_args.push_back(v);
3072 [ + - ]: 42 : fcall->args.push_back(e->components[i].expr_index);
3073 : : }
3074 : :
3075 : : // If this code snippet is assigning to an lvalue,
3076 : : // add a final argument for the rvalue.
3077 [ + + ]: 183124 : if (lvalue_p)
3078 : : {
3079 : : // Modify the fdecl so it carries a single pe_long formal
3080 : : // argument called "value".
3081 : :
3082 : : // FIXME: For the time being we only support setting target
3083 : : // variables which have base types; these are 'pe_long' in
3084 : : // stap's type vocabulary. Strings and pointers might be
3085 : : // reasonable, some day, but not today.
3086 : :
3087 [ + - ][ + - ]: 18 : vardecl *v = new vardecl;
3088 : 18 : v->type = pe_long;
3089 [ + - ]: 18 : v->name = "value";
3090 : 18 : v->tok = e->tok;
3091 [ + - ]: 18 : fdecl->formal_args.push_back(v);
3092 : : // NB: We don't know the value for fcall argument yet.
3093 : : // (see target_symbol_setter_functioncalls)
3094 : : }
3095 : :
3096 : : // Add the synthesized decl to the session, and return the call.
3097 : 183124 : fdecl->join (session);
3098 : 183124 : return fcall;
3099 : : }
3100 : :
3101 : : expression*
3102 : 32941 : dwarf_pretty_print::deref (target_symbol* e)
3103 : : {
3104 : : static unsigned tick = 0;
3105 : :
3106 [ + + ]: 32941 : if (!deref_p)
3107 : : {
3108 [ + - ][ + - ]: 442 : assert (pointer && e->components.empty());
[ - + ]
3109 : 442 : return pointer;
3110 : : }
3111 : :
3112 : 32499 : bool lvalue_p = false;
3113 [ + - ][ + - ]: 32499 : string name = "_dwarf_pretty_print_deref_" + lex_cast(tick++);
[ + - ]
3114 : :
3115 [ + - ]: 32499 : string code;
3116 : 32499 : exp_type type = pe_long;
3117 [ + + ]: 32499 : if (pointer)
3118 [ + - ][ + - ]: 8596 : code = dw.literal_stmt_for_pointer (&pointer_type, e, false, type);
[ + - ]
3119 [ + - ][ + - ]: 23903 : else if (!local.empty())
3120 [ + + ][ + - ]: 23903 : code = dw.literal_stmt_for_local (scopes, pc, local, e, false, type);
[ + - ]
3121 : : else
3122 [ # # ][ # # ]: 0 : code = dw.literal_stmt_for_return (&scopes[0], pc, e, false, type);
[ # # ]
3123 : :
3124 : : return synthetic_embedded_deref_call(dw.sess, name, code, type,
3125 [ + - ][ + - ]: 32941 : userspace_p, lvalue_p, e, pointer);
[ + - ]
3126 : : }
3127 : :
3128 : :
3129 : : bool
3130 : 32941 : dwarf_pretty_print::push_deref (print_format* pf, const string& fmt,
3131 : : target_symbol* e)
3132 : : {
3133 : 32941 : expression* e2 = NULL;
3134 : : try
3135 : : {
3136 [ + + ]: 32941 : e2 = deref (e);
3137 : : }
3138 [ - + ]: 298 : catch (const semantic_error&)
3139 : : {
3140 [ - + ]: 149 : pf->raw_components.append ("?");
3141 : 149 : return false;
3142 : : }
3143 [ + - ]: 32792 : pf->raw_components.append (fmt);
3144 [ + - ]: 32792 : pf->args.push_back (e2);
3145 : 32941 : return true;
3146 : : }
3147 : :
3148 : :
3149 : : void
3150 : 1554 : dwarf_var_expanding_visitor::visit_target_symbol_saved_return (target_symbol* e)
3151 : : {
3152 : : // Get the full name of the target symbol.
3153 [ + - ]: 1554 : stringstream ts_name_stream;
3154 [ + - ]: 1554 : e->print(ts_name_stream);
3155 [ + - ]: 1554 : string ts_name = ts_name_stream.str();
3156 : :
3157 : : // Check and make sure we haven't already seen this target
3158 : : // variable in this return probe. If we have, just return our
3159 : : // last replacement.
3160 [ + - ]: 1554 : map<string, expression *>::iterator i = return_ts_map.find(ts_name);
3161 [ + - ][ + + ]: 1554 : if (i != return_ts_map.end())
3162 : : {
3163 [ + - ][ + - ]: 420 : provide (i->second);
3164 : : return;
3165 : : }
3166 : :
3167 : : // Attempt the expansion directly first, so if there's a problem with the
3168 : : // variable we won't have a bogus entry probe lying around. Like in
3169 : : // saveargs(), we pretend for a moment that we're not in a .return.
3170 : 1134 : bool saved_has_return = q.has_return;
3171 : 1134 : q.has_return = false;
3172 : 1134 : expression *repl = e;
3173 [ + - ]: 1134 : replace (repl);
3174 : 1134 : q.has_return = saved_has_return;
3175 [ - + ]: 1134 : target_symbol* n = dynamic_cast<target_symbol*>(repl);
3176 [ + + ][ + - ]: 1134 : if (n && n->saved_conversion_error)
3177 : : {
3178 [ + - ]: 44 : provide (repl);
3179 : : return;
3180 : : }
3181 : :
3182 : : expression *exp;
3183 [ + - + - ]: 2180 : if (!q.has_process &&
[ + - ]
3184 [ + - ]: 1090 : strverscmp(q.sess.kernel_base_release.c_str(), "2.6.25") >= 0)
3185 [ + - ]: 1090 : exp = gen_kretprobe_saved_return(repl);
3186 : : else
3187 [ # # ][ # # ]: 0 : exp = gen_mapped_saved_return(repl, e->sym_name());
[ # # ]
3188 : :
3189 : : // Provide the variable to our parent so it can be used as a
3190 : : // substitute for the target symbol.
3191 [ + - ]: 1090 : provide (exp);
3192 : :
3193 : : // Remember this replacement since we might be able to reuse
3194 : : // it later if the same return probe references this target
3195 : : // symbol again.
3196 [ + - ][ + - ]: 1554 : return_ts_map[ts_name] = exp;
[ + + ][ + - ]
[ + + ]
3197 : : }
3198 : :
3199 : : static expression*
3200 : 1093 : gen_mapped_saved_return(systemtap_session &sess, expression* e,
3201 : : const string& name,
3202 : : block *& add_block, bool& add_block_tid,
3203 : : block *& add_call_probe, bool& add_call_probe_tid)
3204 : : {
3205 : : static unsigned tick = 0;
3206 : :
3207 : : // We've got to do several things here to handle target
3208 : : // variables in return probes.
3209 : :
3210 : : // (1) Synthesize two global arrays. One is the cache of the
3211 : : // target variable and the other contains a thread specific
3212 : : // nesting level counter. The arrays will look like
3213 : : // this:
3214 : : //
3215 : : // _entry_tvar_{name}_{num}
3216 : : // _entry_tvar_{name}_{num}_ctr
3217 : :
3218 : : string aname = (string("_entry_tvar_")
3219 : : + name
3220 [ + - ][ + - ]: 1093 : + "_" + lex_cast(tick++));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3221 [ + - ][ + - ]: 1093 : vardecl* vd = new vardecl;
3222 [ + - ]: 1093 : vd->name = aname;
3223 : 1093 : vd->tok = e->tok;
3224 [ + - ]: 1093 : sess.globals.push_back (vd);
3225 : :
3226 [ + - ]: 1093 : string ctrname = aname + "_ctr";
3227 [ + - ][ + - ]: 1093 : vd = new vardecl;
3228 [ + - ]: 1093 : vd->name = ctrname;
3229 : 1093 : vd->tok = e->tok;
3230 [ + - ]: 1093 : sess.globals.push_back (vd);
3231 : :
3232 : : // (2) Create a new code block we're going to insert at the
3233 : : // beginning of this probe to get the cached value into a
3234 : : // temporary variable. We'll replace the target variable
3235 : : // reference with the temporary variable reference. The code
3236 : : // will look like this:
3237 : : //
3238 : : // _entry_tvar_tid = tid()
3239 : : // _entry_tvar_{name}_{num}_tmp
3240 : : // = _entry_tvar_{name}_{num}[_entry_tvar_tid,
3241 : : // _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]]
3242 : : // delete _entry_tvar_{name}_{num}[_entry_tvar_tid,
3243 : : // _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]--]
3244 : : // if (! _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid])
3245 : : // delete _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]
3246 : :
3247 : : // (2a) Synthesize the tid temporary expression, which will look
3248 : : // like this:
3249 : : //
3250 : : // _entry_tvar_tid = tid()
3251 [ + - ][ + - ]: 1093 : symbol* tidsym = new symbol;
3252 [ + - ][ + - ]: 1093 : tidsym->name = string("_entry_tvar_tid");
[ + - ]
3253 : 1093 : tidsym->tok = e->tok;
3254 : :
3255 [ + + ]: 1093 : if (add_block == NULL)
3256 : : {
3257 [ + - ][ + - ]: 949 : add_block = new block;
3258 : 949 : add_block->tok = e->tok;
3259 : : }
3260 : :
3261 [ + + ]: 1093 : if (!add_block_tid)
3262 : : {
3263 : : // Synthesize a functioncall to grab the thread id.
3264 [ + - ][ + - ]: 949 : functioncall* fc = new functioncall;
3265 : 949 : fc->tok = e->tok;
3266 [ + - ][ + - ]: 949 : fc->function = string("tid");
[ + - ]
3267 : :
3268 : : // Assign the tid to '_entry_tvar_tid'.
3269 [ + - ][ + - ]: 949 : assignment* a = new assignment;
3270 : 949 : a->tok = e->tok;
3271 [ + - ]: 949 : a->op = "=";
3272 : 949 : a->left = tidsym;
3273 : 949 : a->right = fc;
3274 : :
3275 [ + - ][ + - ]: 949 : expr_statement* es = new expr_statement;
3276 : 949 : es->tok = e->tok;
3277 : 949 : es->value = a;
3278 [ + - ]: 949 : add_block->statements.push_back (es);
3279 : 949 : add_block_tid = true;
3280 : : }
3281 : :
3282 : : // (2b) Synthesize an array reference and assign it to a
3283 : : // temporary variable (that we'll use as replacement for the
3284 : : // target variable reference). It will look like this:
3285 : : //
3286 : : // _entry_tvar_{name}_{num}_tmp
3287 : : // = _entry_tvar_{name}_{num}[_entry_tvar_tid,
3288 : : // _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]]
3289 : :
3290 [ + - ][ + - ]: 1093 : arrayindex* ai_tvar_base = new arrayindex;
3291 : 1093 : ai_tvar_base->tok = e->tok;
3292 : :
3293 [ + - ][ + - ]: 1093 : symbol* sym = new symbol;
3294 [ + - ]: 1093 : sym->name = aname;
3295 : 1093 : sym->tok = e->tok;
3296 : 1093 : ai_tvar_base->base = sym;
3297 : :
3298 [ + - ]: 1093 : ai_tvar_base->indexes.push_back(tidsym);
3299 : :
3300 : : // We need to create a copy of the array index in its current
3301 : : // state so we can have 2 variants of it (the original and one
3302 : : // that post-decrements the second index).
3303 [ + - ][ + - ]: 1093 : arrayindex* ai_tvar = new arrayindex;
3304 [ + - ][ + - ]: 1093 : arrayindex* ai_tvar_postdec = new arrayindex;
3305 [ + - ]: 1093 : *ai_tvar = *ai_tvar_base;
3306 [ + - ]: 1093 : *ai_tvar_postdec = *ai_tvar_base;
3307 : :
3308 : : // Synthesize the
3309 : : // "_entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]" used as the
3310 : : // second index into the array.
3311 [ + - ][ + - ]: 1093 : arrayindex* ai_ctr = new arrayindex;
3312 : 1093 : ai_ctr->tok = e->tok;
3313 : :
3314 [ + - ][ + - ]: 1093 : sym = new symbol;
3315 [ + - ]: 1093 : sym->name = ctrname;
3316 : 1093 : sym->tok = e->tok;
3317 : 1093 : ai_ctr->base = sym;
3318 [ + - ]: 1093 : ai_ctr->indexes.push_back(tidsym);
3319 [ + - ]: 1093 : ai_tvar->indexes.push_back(ai_ctr);
3320 : :
3321 [ + - ][ + - ]: 1093 : symbol* tmpsym = new symbol;
3322 [ + - ][ + - ]: 1093 : tmpsym->name = aname + "_tmp";
[ + - ]
3323 : 1093 : tmpsym->tok = e->tok;
3324 : :
3325 [ + - ][ + - ]: 1093 : assignment* a = new assignment;
3326 : 1093 : a->tok = e->tok;
3327 [ + - ]: 1093 : a->op = "=";
3328 : 1093 : a->left = tmpsym;
3329 : 1093 : a->right = ai_tvar;
3330 : :
3331 [ + - ][ + - ]: 1093 : expr_statement* es = new expr_statement;
3332 : 1093 : es->tok = e->tok;
3333 : 1093 : es->value = a;
3334 : :
3335 [ + - ]: 1093 : add_block->statements.push_back (es);
3336 : :
3337 : : // (2c) Add a post-decrement to the second array index and
3338 : : // delete the array value. It will look like this:
3339 : : //
3340 : : // delete _entry_tvar_{name}_{num}[_entry_tvar_tid,
3341 : : // _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]--]
3342 : :
3343 [ + - ][ + - ]: 1093 : post_crement* pc = new post_crement;
3344 : 1093 : pc->tok = e->tok;
3345 [ + - ]: 1093 : pc->op = "--";
3346 : 1093 : pc->operand = ai_ctr;
3347 [ + - ]: 1093 : ai_tvar_postdec->indexes.push_back(pc);
3348 : :
3349 [ + - ][ + - ]: 1093 : delete_statement* ds = new delete_statement;
3350 : 1093 : ds->tok = e->tok;
3351 : 1093 : ds->value = ai_tvar_postdec;
3352 : :
3353 [ + - ]: 1093 : add_block->statements.push_back (ds);
3354 : :
3355 : : // (2d) Delete the counter value if it is 0. It will look like
3356 : : // this:
3357 : : // if (! _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid])
3358 : : // delete _entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]
3359 : :
3360 [ + - ][ + - ]: 1093 : ds = new delete_statement;
3361 : 1093 : ds->tok = e->tok;
3362 : 1093 : ds->value = ai_ctr;
3363 : :
3364 [ + - ][ + - ]: 1093 : unary_expression *ue = new unary_expression;
3365 : 1093 : ue->tok = e->tok;
3366 [ + - ]: 1093 : ue->op = "!";
3367 : 1093 : ue->operand = ai_ctr;
3368 : :
3369 [ + - ][ + - ]: 1093 : if_statement *ifs = new if_statement;
3370 : 1093 : ifs->tok = e->tok;
3371 : 1093 : ifs->condition = ue;
3372 : 1093 : ifs->thenblock = ds;
3373 : 1093 : ifs->elseblock = NULL;
3374 : :
3375 [ + - ]: 1093 : add_block->statements.push_back (ifs);
3376 : :
3377 : : // (3) We need an entry probe that saves the value for us in the
3378 : : // global array we created. Create the entry probe, which will
3379 : : // look like this:
3380 : : //
3381 : : // probe kernel.function("{function}").call {
3382 : : // _entry_tvar_tid = tid()
3383 : : // _entry_tvar_{name}_{num}[_entry_tvar_tid,
3384 : : // ++_entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]]
3385 : : // = ${param}
3386 : : // }
3387 : :
3388 [ + + ]: 1093 : if (add_call_probe == NULL)
3389 : : {
3390 [ + - ][ + - ]: 939 : add_call_probe = new block;
3391 : 939 : add_call_probe->tok = e->tok;
3392 : : }
3393 : :
3394 [ + + ]: 1093 : if (!add_call_probe_tid)
3395 : : {
3396 : : // Synthesize a functioncall to grab the thread id.
3397 [ + - ][ + - ]: 949 : functioncall* fc = new functioncall;
3398 : 949 : fc->tok = e->tok;
3399 [ + - ][ + - ]: 949 : fc->function = string("tid");
[ + - ]
3400 : :
3401 : : // Assign the tid to '_entry_tvar_tid'.
3402 [ + - ][ + - ]: 949 : assignment* a = new assignment;
3403 : 949 : a->tok = e->tok;
3404 [ + - ]: 949 : a->op = "=";
3405 : 949 : a->left = tidsym;
3406 : 949 : a->right = fc;
3407 : :
3408 [ + - ][ + - ]: 949 : expr_statement* es = new expr_statement;
3409 : 949 : es->tok = e->tok;
3410 : 949 : es->value = a;
3411 [ + - ][ + - ]: 949 : add_call_probe = new block(add_call_probe, es);
3412 : 949 : add_call_probe_tid = true;
3413 : : }
3414 : :
3415 : : // Save the value, like this:
3416 : : // _entry_tvar_{name}_{num}[_entry_tvar_tid,
3417 : : // ++_entry_tvar_{name}_{num}_ctr[_entry_tvar_tid]]
3418 : : // = ${param}
3419 [ + - ][ + - ]: 1093 : arrayindex* ai_tvar_preinc = new arrayindex;
3420 [ + - ]: 1093 : *ai_tvar_preinc = *ai_tvar_base;
3421 : :
3422 [ + - ][ + - ]: 1093 : pre_crement* preinc = new pre_crement;
3423 : 1093 : preinc->tok = e->tok;
3424 [ + - ]: 1093 : preinc->op = "++";
3425 : 1093 : preinc->operand = ai_ctr;
3426 [ + - ]: 1093 : ai_tvar_preinc->indexes.push_back(preinc);
3427 : :
3428 [ + - ][ + - ]: 1093 : a = new assignment;
3429 : 1093 : a->tok = e->tok;
3430 [ + - ]: 1093 : a->op = "=";
3431 : 1093 : a->left = ai_tvar_preinc;
3432 : 1093 : a->right = e;
3433 : :
3434 [ + - ][ + - ]: 1093 : es = new expr_statement;
3435 : 1093 : es->tok = e->tok;
3436 : 1093 : es->value = a;
3437 : :
3438 [ + - ][ + - ]: 1093 : add_call_probe = new block(add_call_probe, es);
3439 : :
3440 : : // (4) Provide the '_entry_tvar_{name}_{num}_tmp' variable to
3441 : : // our parent so it can be used as a substitute for the target
3442 : : // symbol.
3443 [ + - ][ + - ]: 1093 : delete ai_tvar_base;
3444 [ + - ][ + - ]: 1093 : return tmpsym;
3445 : : }
3446 : :
3447 : :
3448 : : expression*
3449 : 695 : dwarf_var_expanding_visitor::gen_mapped_saved_return(expression* e,
3450 : : const string& name)
3451 : : {
3452 : : return ::gen_mapped_saved_return(q.sess, e, name, add_block,
3453 : : add_block_tid, add_call_probe,
3454 : 695 : add_call_probe_tid);
3455 : : }
3456 : :
3457 : :
3458 : : expression*
3459 : 1090 : dwarf_var_expanding_visitor::gen_kretprobe_saved_return(expression* e)
3460 : : {
3461 : : // The code for this is simple.
3462 : : //
3463 : : // .call:
3464 : : // _set_kretprobe_long(index, $value)
3465 : : //
3466 : : // .return:
3467 : : // _get_kretprobe_long(index)
3468 : : //
3469 : : // (or s/long/string/ for things like $$parms)
3470 : :
3471 : : unsigned index;
3472 [ + - ][ + - ]: 1090 : string setfn, getfn;
3473 : :
3474 : : // We need the caller to predetermine the type of the expression!
3475 [ + + - ]: 1090 : switch (e->type)
3476 : : {
3477 : : case pe_string:
3478 : 4 : index = saved_strings++;
3479 [ + - ]: 4 : setfn = "_set_kretprobe_string";
3480 [ + - ]: 4 : getfn = "_get_kretprobe_string";
3481 : 4 : break;
3482 : : case pe_long:
3483 : 1086 : index = saved_longs++;
3484 [ + - ]: 1086 : setfn = "_set_kretprobe_long";
3485 [ + - ]: 1086 : getfn = "_get_kretprobe_long";
3486 : 1086 : break;
3487 : : default:
3488 [ # # ][ # # ]: 0 : throw semantic_error(_("unknown type to save in kretprobe"), e->tok);
3489 : : }
3490 : :
3491 : : // Create the entry code
3492 : : // _set_kretprobe_{long|string}(index, $value)
3493 : :
3494 [ + + ]: 1090 : if (add_call_probe == NULL)
3495 : : {
3496 [ + - ][ + - ]: 602 : add_call_probe = new block;
3497 : 602 : add_call_probe->tok = e->tok;
3498 : : }
3499 : :
3500 [ + - ][ + - ]: 1090 : functioncall* set_fc = new functioncall;
3501 : 1090 : set_fc->tok = e->tok;
3502 [ + - ]: 1090 : set_fc->function = setfn;
3503 [ + - ][ + - ]: 1090 : set_fc->args.push_back(new literal_number(index));
[ + - ]
3504 [ + - ]: 1090 : set_fc->args.back()->tok = e->tok;
3505 [ + - ]: 1090 : set_fc->args.push_back(e);
3506 : :
3507 [ + - ][ + - ]: 1090 : expr_statement* set_es = new expr_statement;
3508 : 1090 : set_es->tok = e->tok;
3509 : 1090 : set_es->value = set_fc;
3510 : :
3511 [ + - ]: 1090 : add_call_probe->statements.push_back(set_es);
3512 : :
3513 : : // Create the return code
3514 : : // _get_kretprobe_{long|string}(index)
3515 : :
3516 [ + - ][ + - ]: 1090 : functioncall* get_fc = new functioncall;
3517 : 1090 : get_fc->tok = e->tok;
3518 [ + - ]: 1090 : get_fc->function = getfn;
3519 [ + - ][ + - ]: 1090 : get_fc->args.push_back(new literal_number(index));
[ + - ]
3520 [ + - ]: 1090 : get_fc->args.back()->tok = e->tok;
3521 : :
3522 [ + - ][ + - ]: 1090 : return get_fc;
3523 : : }
3524 : :
3525 : :
3526 : : void
3527 : 21248 : dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
3528 : : {
3529 [ + - ]: 21248 : if (null_die(scope_die))
3530 : 21248 : return;
3531 : :
3532 [ + - ][ + - ]: 21248 : target_symbol *tsym = new target_symbol(*e);
3533 : :
3534 [ + - ]: 21248 : bool pretty = (!e->components.empty() &&
3535 [ + + ][ + - ]: 21248 : e->components[0].type == target_symbol::comp_pretty_print);
3536 [ + + ][ + - ]: 21248 : string format = pretty ? "=%s" : "=%#x";
3537 : :
3538 : : // Convert $$parms to sprintf of a list of parms and active local vars
3539 : : // which we recursively evaluate
3540 : :
3541 : : // NB: we synthesize a new token here rather than reusing
3542 : : // e->tok, because print_format::print likes to use
3543 : : // its tok->content.
3544 [ + - ][ + - ]: 21248 : token* pf_tok = new token(*e->tok);
3545 : 21248 : pf_tok->type = tok_identifier;
3546 [ + - ]: 21248 : pf_tok->content = "sprintf";
3547 : :
3548 [ + - ]: 21248 : print_format* pf = print_format::create(pf_tok);
3549 : :
3550 [ + + ][ + - ]: 21248 : if (q.has_return && (e->name == "$$return"))
[ + - ][ + + ]
3551 : : {
3552 [ + - ]: 1213 : tsym->name = "$return";
3553 : :
3554 : : // Ignore any variable that isn't accessible.
3555 : 1213 : tsym->saved_conversion_error = 0;
3556 : 1213 : expression *texp = tsym;
3557 [ + - ]: 1213 : replace (texp); // NB: throws nothing ...
3558 [ + + ]: 1213 : if (tsym->saved_conversion_error) // ... but this is how we know it happened.
3559 : : {
3560 : :
3561 : : }
3562 : : else
3563 : : {
3564 [ + - ]: 1009 : pf->raw_components += "return";
3565 [ + - ]: 1009 : pf->raw_components += format;
3566 [ + - ]: 1213 : pf->args.push_back(texp);
3567 : : }
3568 : : }
3569 : : else
3570 : : {
3571 : : // non-.return probe: support $$parms, $$vars, $$locals
3572 : 20035 : bool first = true;
3573 : : Dwarf_Die result;
3574 [ + - ]: 20035 : vector<Dwarf_Die> scopes = q.dw.getscopes(scope_die);
3575 [ + - ]: 40078 : for (unsigned i = 0; i < scopes.size(); ++i)
3576 : : {
3577 [ + - ][ + + ]: 40078 : if (dwarf_tag(&scopes[i]) == DW_TAG_compile_unit)
3578 : 20035 : break; // we don't want file-level variables
3579 [ + - ][ + + ]: 20043 : if (dwarf_child (&scopes[i], &result) == 0)
3580 [ + + ]: 170424 : do
3581 : : {
3582 [ + - ]: 170424 : switch (dwarf_tag (&result))
[ + + + ]
3583 : : {
3584 : : case DW_TAG_variable:
3585 [ + - ][ + + ]: 43456 : if (e->name == "$$parms")
3586 : 2714 : continue;
3587 : 40742 : break;
3588 : : case DW_TAG_formal_parameter:
3589 [ + - ][ + + ]: 43112 : if (e->name == "$$locals")
3590 : 6 : continue;
3591 : 43106 : break;
3592 : :
3593 : : default:
3594 : 83856 : continue;
3595 : : }
3596 : :
3597 [ + - ]: 83848 : const char *diename = dwarf_diename (&result);
3598 [ + + ]: 83848 : if (! diename) continue;
3599 : :
3600 [ + + ]: 83837 : if (! first)
3601 [ + - ]: 64297 : pf->raw_components += " ";
3602 [ + - ]: 83837 : pf->raw_components += diename;
3603 : 83837 : first = false;
3604 : :
3605 : : // Write a placeholder for ugly aggregates
3606 : : Dwarf_Die type;
3607 [ + + ][ + - ]: 83837 : if (!pretty && dwarf_attr_die(&result, DW_AT_type, &type))
[ + - ][ + + ]
3608 : : {
3609 [ + - ]: 82285 : q.dw.resolve_unqualified_inner_typedie(&type, &type, e);
3610 [ + - ]: 82285 : switch (dwarf_tag(&type))
[ + + + ]
3611 : : {
3612 : : case DW_TAG_union_type:
3613 : : case DW_TAG_structure_type:
3614 : : case DW_TAG_class_type:
3615 [ + - ]: 2591 : pf->raw_components += "={...}";
3616 : 2591 : continue;
3617 : :
3618 : : case DW_TAG_array_type:
3619 [ + - ]: 1705 : pf->raw_components += "=[...]";
3620 : 1705 : continue;
3621 : : }
3622 : : }
3623 : :
3624 [ + - ]: 79541 : tsym->name = "$";
3625 [ + - ]: 79541 : tsym->name += diename;
3626 : :
3627 : : // Ignore any variable that isn't accessible.
3628 : 79541 : tsym->saved_conversion_error = 0;
3629 : 79541 : expression *texp = tsym;
3630 [ + - ]: 79541 : replace (texp); // NB: throws nothing ...
3631 [ + + ]: 79541 : if (tsym->saved_conversion_error) // ... but this is how we know it happened.
3632 : : {
3633 [ - + ]: 28089 : if (q.sess.verbose>2)
3634 : : {
3635 [ # # ]: 0 : for (const semantic_error *c = tsym->saved_conversion_error;
3636 : : c != 0;
3637 : : c = c->chain) {
3638 [ # # ][ # # ]: 0 : clog << _("variable location problem [man error::dwarf]: ") << c->what() << endl;
[ # # ]
3639 : : }
3640 : : }
3641 : :
3642 [ + - ]: 28089 : pf->raw_components += "=?";
3643 : : }
3644 : : else
3645 : : {
3646 [ + - ]: 51452 : pf->raw_components += format;
3647 [ + - ]: 170424 : pf->args.push_back(texp);
3648 : : }
3649 : : }
3650 [ + - ]: 170424 : while (dwarf_siblingof (&result, &result) == 0);
3651 [ + - ]: 20035 : }
3652 : : }
3653 : :
3654 [ + - ][ + - ]: 21248 : pf->components = print_format::string_to_components(pf->raw_components);
[ + - ]
3655 : 21248 : pf->type = pe_string;
3656 [ + - ][ + - ]: 21248 : provide (pf);
3657 : : }
3658 : :
3659 : :
3660 : : void
3661 : 201702 : dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e)
3662 : : {
3663 : 605107 : assert(e->name.size() > 0
3664 : : && ((e->name[0] == '$' && e->target_name == "")
3665 [ + - + + : 605107 : || (e->name == "@var" && e->target_name != "")));
- + + - -
+ ]
3666 : 201702 : visited = true;
3667 [ + + ][ + + ]: 201702 : bool defined_being_checked = (defined_ops.size() > 0 && (defined_ops.top()->operand == e));
3668 : : // In this mode, we avoid hiding errors or generating extra code such as for .return saved $vars
3669 : :
3670 : : try
3671 : : {
3672 [ + - ]: 201702 : bool lvalue = is_active_lvalue(e);
3673 [ + + ][ + + ]: 201702 : if (lvalue && !q.sess.guru_mode)
3674 [ + - ][ + - ]: 1 : throw semantic_error(_("write to target variable not permitted; need stap -g"), e->tok);
3675 : :
3676 : : // XXX: process $context vars should be writable
3677 : :
3678 : : // See if we need to generate a new probe to save/access function
3679 : : // parameters from a return probe. PR 1382.
3680 [ + + ][ + + ]: 223428 : if (q.has_return
[ + + ][ + + ]
[ + + ]
3681 : 19365 : && !defined_being_checked
3682 [ + - ]: 18960 : && e->name != "$return" // not the special return-value variable handled below
3683 [ + - ]: 2767 : && e->name != "$$return") // nor the other special variable handled below
3684 : : {
3685 [ - + ]: 1554 : if (lvalue)
3686 [ # # ][ # # ]: 0 : throw semantic_error(_("write to target variable not permitted in .return probes"), e->tok);
3687 [ + - ]: 1554 : visit_target_symbol_saved_return(e);
3688 : : return;
3689 : : }
3690 : :
3691 [ + - ][ + + ]: 217958 : if (e->name == "$$vars" || e->name == "$$parms" || e->name == "$$locals"
[ + - ][ + + ]
[ + - ][ + + ]
[ + + ][ + + ]
[ + + ]
3692 [ + - ]: 17811 : || (q.has_return && (e->name == "$$return")))
3693 : : {
3694 [ - + ]: 21248 : if (lvalue)
3695 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot write to context variable"), e->tok);
3696 : :
3697 [ - + ]: 21248 : if (e->addressof)
3698 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of context variable"), e->tok);
3699 : :
3700 [ + - ][ + - ]: 21248 : e->assert_no_components("dwarf", true);
[ + - ]
3701 : :
3702 [ + - ]: 21248 : visit_target_symbol_context(e);
3703 : : return;
3704 : : }
3705 : :
3706 [ + - ][ + + ]: 182716 : if (!e->components.empty() &&
[ + + ][ + + ]
3707 [ + - ]: 3817 : e->components.back().type == target_symbol::comp_pretty_print)
3708 : : {
3709 [ - + ]: 1581 : if (lvalue)
3710 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot write to pretty-printed variable"), e->tok);
3711 : :
3712 [ - + ][ # # ]: 1581 : if (q.has_return && (e->name == "$return"))
[ # # ][ - + ]
3713 : : {
3714 : : dwarf_pretty_print dpp (q.dw, scope_die, addr,
3715 [ # # ]: 0 : q.has_process, *e);
3716 [ # # ][ # # ]: 0 : dpp.expand()->visit(this);
[ # # ]
3717 : : }
3718 : : else
3719 : : {
3720 [ + - ]: 1581 : dwarf_pretty_print dpp (q.dw, getscopes(e), addr,
3721 : : e->sym_name(),
3722 [ + - ][ + - ]: 1581 : q.has_process, *e);
[ + - ]
3723 [ + - ][ + - ]: 1581 : dpp.expand()->visit(this);
[ + - ]
3724 : : }
3725 : : return;
3726 : : }
3727 : :
3728 : 177318 : bool userspace_p = q.has_process;
3729 : : string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
3730 : : + "_" + e->sym_name()
3731 [ + + ][ + - ]: 177318 : + "_" + lex_cast(tick++));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
3732 : :
3733 : :
3734 : 177318 : exp_type type = pe_long;
3735 [ + - ]: 177318 : string code;
3736 [ + + ][ + - ]: 177318 : if (q.has_return && (e->name == "$return"))
[ + + ][ + + ]
3737 [ + + ][ + - ]: 16240 : code = q.dw.literal_stmt_for_return (scope_die, addr, e, lvalue, type);
[ + - ]
3738 : : else
3739 [ + - ]: 161078 : code = q.dw.literal_stmt_for_local (getscopes(e), addr, e->sym_name(),
3740 [ + - ][ + + ]: 161078 : e, lvalue, type);
[ + - ][ + - ]
[ + - ]
3741 : :
3742 : : functioncall* n = synthetic_embedded_deref_call(q.sess, fname, code, type,
3743 [ + - ]: 143258 : userspace_p, lvalue, e);
3744 : :
3745 [ + + ]: 143258 : if (lvalue)
3746 : : {
3747 : : // Provide the functioncall to our parent, so that it can be
3748 : : // used to substitute for the assignment node immediately above
3749 : : // us.
3750 [ + - ][ - + ]: 16 : assert(!target_symbol_setter_functioncalls.empty());
3751 [ + - ]: 16 : *(target_symbol_setter_functioncalls.top()) = n;
3752 : : }
3753 : :
3754 : : // Revisit the functioncall so arguments can be expanded.
3755 [ + - ][ + - ]: 235763 : n->visit (this);
[ + - ]
3756 : : }
3757 [ - + ]: 68122 : catch (const semantic_error& er)
3758 : : {
3759 : : // We suppress this error message, and pass the unresolved
3760 : : // target_symbol to the next pass. We hope that this value ends
3761 : : // up not being referenced after all, so it can be optimized out
3762 : : // quietly.
3763 [ - + ]: 34061 : e->chain (er);
3764 [ - + ]: 34061 : provide (e);
3765 : : }
3766 : : }
3767 : :
3768 : :
3769 : : void
3770 : 391 : dwarf_var_expanding_visitor::visit_cast_op (cast_op *e)
3771 : : {
3772 : : // Fill in our current module context if needed
3773 [ + + ]: 391 : if (e->module.empty())
3774 : 347 : e->module = q.dw.module_name;
3775 : :
3776 : 391 : var_expanding_visitor::visit_cast_op(e);
3777 : 391 : }
3778 : :
3779 : :
3780 : : void
3781 : 696 : dwarf_var_expanding_visitor::visit_entry_op (entry_op *e)
3782 : : {
3783 : 696 : expression *repl = e;
3784 [ + + ]: 696 : if (q.has_return)
3785 : : {
3786 : : // expand the operand as if it weren't a return probe
3787 : 695 : q.has_return = false;
3788 : 695 : replace (e->operand);
3789 : 695 : q.has_return = true;
3790 : :
3791 : : // XXX it would be nice to use gen_kretprobe_saved_return when available,
3792 : : // but it requires knowing the types already, which is problematic for
3793 : : // arbitrary expressons.
3794 [ + - ][ + - ]: 695 : repl = gen_mapped_saved_return (e->operand, "entry");
[ + - ]
3795 : : }
3796 : 696 : provide (repl);
3797 : 696 : }
3798 : :
3799 : : void
3800 : 5 : dwarf_var_expanding_visitor::visit_perf_op (perf_op *e)
3801 : : {
3802 [ + - ][ + - ]: 5 : token* t = new token;
3803 [ + - ]: 5 : string e_lit_val = e->operand->value;
3804 : :
3805 : 5 : t->location = e->tok->location;
3806 : 5 : t->type = tok_identifier;
3807 [ + - ]: 5 : t->content = e_lit_val;
3808 : :
3809 [ + - ][ + - ]: 5 : add_block = new block;
3810 : :
3811 : 5 : systemtap_session &s = this->q.sess;
3812 : 5 : map<string, pair<string,derived_probe*> >::iterator it;
3813 : : // Find the associated perf.counter probe
3814 [ + - ][ + + ]: 14 : for (it=s.perf_counters.begin();
3815 [ + - ]: 7 : it != s.perf_counters.end();
3816 : : it++)
3817 [ + - ][ + + ]: 5 : if ((*it).first == e_lit_val)
3818 : : {
3819 : : // if perf .function("name") omitted, then set it to this process name
3820 [ + - ][ + + ]: 4 : if ((*it).second.first.length() == 0)
3821 [ + - ]: 1 : ((*it).second).first = this->q.user_path;
3822 [ + - ][ + + ]: 4 : if (((*it).second).first == this->q.user_path)
3823 : 3 : break;
3824 : : }
3825 : :
3826 [ + - ][ + + ]: 5 : if (it != s.perf_counters.end())
3827 : : {
3828 [ + - ]: 3 : perf_counter_refs.insert((*it).second.second);
3829 : : // __perf_read_N is assigned in the probe prologue
3830 [ + - ][ + - ]: 3 : symbol* sym = new symbol;
3831 : 3 : sym->tok = t;
3832 [ + - ][ + - ]: 3 : sym->name = "__perf_read_" + (*it).first;
[ + - ]
3833 [ + - ]: 3 : provide (sym);
3834 : : }
3835 : : else
3836 [ + - ][ + - ]: 5 : throw semantic_error(_F("perf counter '%s' not defined", e_lit_val.c_str()));
[ + - ][ + - ]
3837 : 3 : }
3838 : :
3839 : : vector<Dwarf_Die>&
3840 : 1 : dwarf_var_expanding_visitor::getcuscope(target_symbol *e)
3841 : : {
3842 : 1 : Dwarf_Off cu_off = 0;
3843 : 1 : const char *cu_name = NULL;
3844 : :
3845 [ + - ][ + - ]: 1 : string prefixed_srcfile = string("*/") + e->cu_name;
[ + - ]
3846 : :
3847 : 1 : Dwarf_Off off = 0;
3848 : : size_t cuhl;
3849 : : Dwarf_Off noff;
3850 : : Dwarf_Off module_bias;
3851 [ + - ]: 1 : Dwarf *dw = dwfl_module_getdwarf(q.dw.module, &module_bias);
3852 [ + - ][ + - ]: 134 : while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
3853 : : {
3854 : : Dwarf_Die die_mem;
3855 : : Dwarf_Die *die;
3856 [ + - ]: 134 : die = dwarf_offdie (dw, off + cuhl, &die_mem);
3857 : :
3858 : : /* We are not interested in partial units. */
3859 [ + - ][ + - ]: 134 : if (dwarf_tag (die) == DW_TAG_compile_unit)
3860 : : {
3861 [ + - ]: 134 : const char *die_name = dwarf_diename (die);
3862 [ + - ][ + + ]: 134 : if (strcmp (die_name, e->cu_name.c_str()) == 0) // Perfect match.
3863 : : {
3864 : 1 : cu_name = die_name;
3865 : 1 : cu_off = off + cuhl;
3866 : : break;
3867 : : }
3868 : :
3869 [ + - ][ + - ]: 133 : if (fnmatch(prefixed_srcfile.c_str(), die_name, 0) == 0)
[ + + ]
3870 [ - + ][ # # ]: 1 : if (cu_name == NULL || strlen (die_name) < strlen (cu_name))
3871 : : {
3872 : 1 : cu_name = die_name;
3873 : 1 : cu_off = off + cuhl;
3874 : : }
3875 : : }
3876 : 133 : off = noff;
3877 : : }
3878 : :
3879 [ - + ]: 1 : if (cu_name == NULL)
3880 : : throw semantic_error ("unable to find CU '" + e->cu_name + "'"
3881 : : + " while searching for '" + e->target_name + "'",
3882 [ # # ][ # # ]: 0 : e->tok);
[ # # ][ # # ]
[ # # ][ # # ]
3883 : :
3884 [ + - ][ + - ]: 1 : vector<Dwarf_Die> *cu_scope = new vector<Dwarf_Die>;
3885 : : Dwarf_Die cu_die;
3886 [ + - ]: 1 : dwarf_offdie (dw, cu_off, &cu_die);
3887 [ + - ]: 1 : cu_scope->push_back(cu_die);
3888 [ + - ]: 1 : return *cu_scope;
3889 : : }
3890 : :
3891 : : vector<Dwarf_Die>&
3892 : 162659 : dwarf_var_expanding_visitor::getscopes(target_symbol *e)
3893 : : {
3894 : : // "static globals" can only be found in the top-level CU.
3895 [ + + ][ + - ]: 162659 : if (e->name == "@var" && e->cu_name != "")
[ + + ]
3896 : 1 : return this->getcuscope(e);
3897 : :
3898 [ + + ]: 162658 : if (scopes.empty())
3899 : : {
3900 [ + - ]: 34526 : if(scope_die != NULL)
3901 [ + - ]: 34526 : scopes = q.dw.getscopes(scope_die);
3902 [ - + ]: 34526 : if (scopes.empty())
3903 : : //throw semantic_error (_F("unable to find any scopes containing %d", addr), e->tok);
3904 : : // ((scope_die == NULL) ? "" : (string (" in ") + (dwarf_diename(scope_die) ?: "<unknown>") + "(" + (dwarf_diename(q.dw.cu) ?: "<unknown>") ")" ))
3905 : : throw semantic_error ("unable to find any scopes containing "
3906 : : + lex_cast_hex(addr)
3907 : : + ((scope_die == NULL) ? ""
3908 : : : (string (" in ")
3909 [ # # ]: 0 : + (dwarf_diename(scope_die) ?: "<unknown>")
3910 [ # # ]: 0 : + "(" + (dwarf_diename(q.dw.cu) ?: "<unknown>")
3911 : : + ")"))
3912 : : + " while searching for local '"
3913 : : + e->sym_name() + "'",
3914 [ # # ][ # # ]: 0 : e->tok);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# # # #
# ]
3915 : : }
3916 : 162659 : return scopes;
3917 : : }
3918 : :
3919 : :
3920 [ # # ]: 0 : struct dwarf_cast_expanding_visitor: public var_expanding_visitor
3921 : : {
3922 : : systemtap_session& s;
3923 : : dwarf_builder& db;
3924 : :
3925 : 1218 : dwarf_cast_expanding_visitor(systemtap_session& s, dwarf_builder& db):
3926 : 1218 : s(s), db(db) {}
3927 : : void visit_cast_op (cast_op* e);
3928 : : void filter_special_modules(string& module);
3929 : : };
3930 : :
3931 : :
3932 [ - + ]: 9337 : struct dwarf_cast_query : public base_query
3933 : : {
3934 : : cast_op& e;
3935 : : const bool lvalue;
3936 : : const bool userspace_p;
3937 : : functioncall*& result;
3938 : :
3939 : 9337 : dwarf_cast_query(dwflpp& dw, const string& module, cast_op& e, bool lvalue,
3940 : : const bool userspace_p, functioncall*& result):
3941 : : base_query(dw, module), e(e), lvalue(lvalue),
3942 : 9337 : userspace_p(userspace_p), result(result) {}
3943 : :
3944 : : void handle_query_module();
3945 : 0 : void query_library (const char *) {}
3946 : 0 : void query_plt (const char *entry, size_t addr) {}
3947 : : };
3948 : :
3949 : :
3950 : : void
3951 : 9335 : dwarf_cast_query::handle_query_module()
3952 : : {
3953 : : static unsigned tick = 0;
3954 : :
3955 [ + - ]: 9335 : if (result)
3956 : : return;
3957 : :
3958 : : // look for the type in any CU
3959 : 9335 : Dwarf_Die* type_die = NULL;
3960 [ + - ][ - + ]: 9335 : if (startswith(e.type_name, "class "))
3961 : : {
3962 : : // normalize to match dwflpp::global_alias_caching_callback
3963 [ # # ][ # # ]: 0 : string struct_name = "struct " + e.type_name.substr(6);
[ # # ]
3964 [ # # ][ # # ]: 0 : type_die = dw.declaration_resolve_other_cus(struct_name);
3965 : : }
3966 : : else
3967 [ + - ]: 9335 : type_die = dw.declaration_resolve_other_cus(e.type_name);
3968 : :
3969 : : // NB: We now index the types as "struct name"/"union name"/etc. instead of
3970 : : // just "name". But since we didn't require users to be explicit before, and
3971 : : // actually sort of discouraged it, we must be flexible now. So if a lookup
3972 : : // fails with a bare name, try augmenting it.
3973 [ + + ][ + - ]: 45647 : if (!type_die &&
[ + - ][ + - ]
[ + - ][ + + ]
3974 [ + - ]: 9078 : !startswith(e.type_name, "class ") &&
3975 [ + - ]: 9078 : !startswith(e.type_name, "struct ") &&
3976 [ + - ]: 9078 : !startswith(e.type_name, "union ") &&
3977 [ + - ]: 9078 : !startswith(e.type_name, "enum "))
3978 : : {
3979 [ + - ][ + - ]: 9078 : type_die = dw.declaration_resolve_other_cus("struct " + e.type_name);
[ + - ]
3980 [ + + ]: 9078 : if (!type_die)
3981 [ + - ][ + - ]: 797 : type_die = dw.declaration_resolve_other_cus("union " + e.type_name);
[ + - ]
3982 [ + + ]: 9078 : if (!type_die)
3983 [ + - ][ + - ]: 797 : type_die = dw.declaration_resolve_other_cus("enum " + e.type_name);
[ + - ]
3984 : : }
3985 : :
3986 [ + + ]: 9335 : if (!type_die)
3987 : : return;
3988 : :
3989 [ + - ]: 8538 : string code;
3990 : 8538 : exp_type type = pe_long;
3991 : :
3992 : : try
3993 : : {
3994 : : Dwarf_Die cu_mem;
3995 [ + - ][ + - ]: 8538 : dw.focus_on_cu(dwarf_diecu(type_die, &cu_mem, NULL, NULL));
3996 : :
3997 [ + - ][ + - ]: 17076 : if (!e.components.empty() &&
[ + + ][ + + ]
3998 [ + - ]: 8538 : e.components.back().type == target_symbol::comp_pretty_print)
3999 : : {
4000 [ - + ]: 24 : if (lvalue)
4001 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot write to pretty-printed variable"), e.tok);
4002 : :
4003 [ + - ]: 24 : dwarf_pretty_print dpp(dw, type_die, e.operand, true, userspace_p, e);
4004 [ + - ]: 24 : result = dpp.expand();
4005 [ + - ]: 24 : return;
4006 : : }
4007 : :
4008 [ + + ][ + - ]: 8514 : code = dw.literal_stmt_for_pointer (type_die, &e, lvalue, type);
[ + - ]
4009 : : }
4010 [ - + ]: 2578 : catch (const semantic_error& er)
4011 : : {
4012 : : // NB: we can have multiple errors, since a @cast
4013 : : // may be attempted using several different modules:
4014 : : // @cast(ptr, "type", "module1:module2:...")
4015 [ - + ]: 1289 : e.chain (er);
4016 : : }
4017 : :
4018 [ + - ][ + + ]: 8514 : if (code.empty())
4019 : : return;
4020 : :
4021 : : string fname = (string(lvalue ? "_dwarf_cast_set" : "_dwarf_cast_get")
4022 : : + "_" + e.sym_name()
4023 [ + + ][ + - ]: 7225 : + "_" + lex_cast(tick++));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
4024 : :
4025 : : result = synthetic_embedded_deref_call(dw.sess, fname, code, type,
4026 [ + - ][ + - ]: 9335 : userspace_p, lvalue, &e, e.operand);
[ + - ][ + + ]
4027 : : }
4028 : :
4029 : :
4030 : 9337 : void dwarf_cast_expanding_visitor::filter_special_modules(string& module)
4031 : : {
4032 : : // look for "<path/to/header>" or "kernel<path/to/header>"
4033 : : // for those cases, build a module including that header
4034 [ + + + + : 18589 : if (module[module.size() - 1] == '>' &&
+ - ][ + + ]
4035 : 9252 : (module[0] == '<' || startswith(module, "kernel<")))
4036 : : {
4037 [ + - ]: 4628 : string cached_module;
4038 [ + - ]: 4628 : if (s.use_cache)
4039 : : {
4040 : : // see if the cached module exists
4041 [ + - ][ + - ]: 4628 : cached_module = find_typequery_hash(s, module);
[ + - ]
4042 [ + - ][ + - ]: 4628 : if (!cached_module.empty() && !s.poison_cache)
[ + - ][ + - ]
4043 : : {
4044 [ + - ][ + - ]: 4628 : int fd = open(cached_module.c_str(), O_RDONLY);
4045 [ + + ]: 4628 : if (fd != -1)
4046 : : {
4047 [ - + ]: 4618 : if (s.verbose > 2)
4048 : : //TRANSLATORS: Here we're using a cached module.
4049 [ # # ][ # # ]: 0 : clog << _("Pass 2: using cached ") << cached_module << endl;
[ # # ]
4050 [ + - ]: 4618 : module = cached_module;
4051 [ + - ]: 4618 : close(fd);
4052 : 9337 : return;
4053 : : }
4054 : : }
4055 : : }
4056 : :
4057 : : // no cached module, time to make it
4058 [ + - ][ + - ]: 10 : if (make_typequery(s, module) == 0)
4059 : : {
4060 : : // try to save typequery in the cache
4061 [ + - ]: 10 : if (s.use_cache)
4062 [ + - ]: 10 : copy_file(module, cached_module, s.verbose > 2);
4063 [ + - ][ + + ]: 4628 : }
4064 : : }
4065 : : }
4066 : :
4067 : :
4068 : 8504 : void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
4069 : : {
4070 [ + - ]: 8504 : bool lvalue = is_active_lvalue(e);
4071 [ + + ][ - + ]: 8504 : if (lvalue && !s.guru_mode)
4072 [ # # ][ # # ]: 0 : throw semantic_error(_("write to @cast context variable not permitted; need stap -g"), e->tok);
4073 : :
4074 [ + - ][ + + ]: 8504 : if (e->module.empty())
4075 [ + - ]: 1865 : e->module = "kernel"; // "*" may also be reasonable to search all kernel modules
4076 : :
4077 : 8504 : functioncall* result = NULL;
4078 : :
4079 : : // split the module string by ':' for alternatives
4080 [ + - ]: 8504 : vector<string> modules;
4081 [ + - ][ + - ]: 8504 : tokenize(e->module, modules, ":");
[ + - ]
4082 : 8504 : bool userspace_p=false; // PR10601
4083 [ + + ][ + + ]: 17841 : for (unsigned i = 0; !result && i < modules.size(); ++i)
[ + + ]
4084 : : {
4085 : 9337 : string& module = modules[i];
4086 [ + - ]: 9337 : filter_special_modules(module);
4087 : :
4088 : : // NB: This uses '/' to distinguish between kernel modules and userspace,
4089 : : // which means that userspace modules won't get any PATH searching.
4090 : : dwflpp* dw;
4091 : : try
4092 : : {
4093 [ + - ]: 9337 : userspace_p=is_user_module (module);
4094 [ + + ]: 9337 : if (! userspace_p)
4095 : : {
4096 : : // kernel or kernel module target
4097 [ + - ]: 9323 : dw = db.get_kern_dw(s, module);
4098 : : }
4099 : : else
4100 : : {
4101 [ + - ][ + - ]: 14 : module = find_executable (module, "", s.sysenv); // canonicalize it
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ # # ]
4102 [ + - ]: 14 : dw = db.get_user_dw(s, module);
4103 : : }
4104 : : }
4105 : : catch (const semantic_error& er)
4106 : : {
4107 : : /* ignore and go to the next module */
4108 : : continue;
4109 : : }
4110 : :
4111 [ + - ]: 9337 : dwarf_cast_query q (*dw, module, *e, lvalue, userspace_p, result);
4112 [ + - ]: 9337 : dw->iterate_over_modules(&query_module, &q);
4113 [ + - ]: 9337 : }
4114 : :
4115 [ + + ]: 8504 : if (!result)
4116 : : {
4117 : : // We pass the unresolved cast_op to the next pass, and hope
4118 : : // that this value ends up not being referenced after all, so
4119 : : // it can be optimized out quietly.
4120 [ + - ]: 1255 : provide (e);
4121 : 8504 : return;
4122 : : }
4123 : :
4124 [ + + ]: 7249 : if (lvalue)
4125 : : {
4126 : : // Provide the functioncall to our parent, so that it can be
4127 : : // used to substitute for the assignment node immediately above
4128 : : // us.
4129 [ + - ][ - + ]: 2 : assert(!target_symbol_setter_functioncalls.empty());
4130 [ + - ]: 2 : *(target_symbol_setter_functioncalls.top()) = result;
4131 : : }
4132 : :
4133 [ + - ][ + - ]: 8504 : result->visit (this);
[ + + ]
4134 : : }
4135 : :
4136 : :
4137 : : void
4138 : 317149 : dwarf_derived_probe::printsig (ostream& o) const
4139 : : {
4140 : : // Instead of just printing the plain locations, we add a PC value
4141 : : // as a comment as a way of telling e.g. apart multiple inlined
4142 : : // function instances. This is distinct from the verbose/clog
4143 : : // output, since this part goes into the cache hash calculations.
4144 : 317149 : sole_location()->print (o);
4145 : 317149 : o << " /* pc=" << section << "+0x" << hex << addr << dec << " */";
4146 : 317149 : printsig_nested (o);
4147 : 317149 : }
4148 : :
4149 : :
4150 : :
4151 : : void
4152 : 318359 : dwarf_derived_probe::join_group (systemtap_session& s)
4153 : : {
4154 : : // skip probes which are paired entry-handlers
4155 [ + + ][ + + ]: 318359 : if (!has_return && (saved_longs || saved_strings))
[ + + ]
4156 : 318359 : return;
4157 : :
4158 [ + + ]: 317756 : if (! s.dwarf_derived_probes)
4159 [ + - ]: 385 : s.dwarf_derived_probes = new dwarf_derived_probe_group ();
4160 : 317756 : s.dwarf_derived_probes->enroll (this);
4161 : : }
4162 : :
4163 : :
4164 : : static bool
4165 : 11891 : kernel_supports_inode_uprobes(systemtap_session& s)
4166 : : {
4167 : : // The arch-supports is new to the builtin inode-uprobes, so it makes a
4168 : : // reasonable indicator of the new API. Else we'll need an autoconf...
4169 : : // see also buildrun.cxx:kernel_built_uprobs()
4170 [ + - ][ + - ]: 23782 : return (s.kernel_config["CONFIG_ARCH_SUPPORTS_UPROBES"] == "y"
[ + - ][ + - ]
[ + - ][ + - ]
[ # # # # ]
4171 [ - + ][ # # ]: 23782 : && s.kernel_config["CONFIG_UPROBES"] == "y");
[ # # ][ # # ]
[ # # ][ - + ]
[ # # ][ - + ]
[ # # # # ]
4172 : : }
4173 : :
4174 : :
4175 : : static bool
4176 : 0 : kernel_supports_inode_uretprobes(systemtap_session& s)
4177 : : {
4178 : : // We need inode-uprobes first, then look for uretprobe_register either as a
4179 : : // real export or in the list possibly accessible by kallsyms.
4180 [ # # ]: 0 : return kernel_supports_inode_uprobes(s) &&
4181 [ # # ][ # # ]: 0 : (s.kernel_exports.count("uretprobe_register") > 0 ||
[ # # ][ # # ]
[ # # ]
[ # # # # ]
4182 [ # # ][ # # ]: 0 : s.kernel_functions.count("uretprobe_register") > 0);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
4183 : : }
4184 : :
4185 : :
4186 : : void
4187 : 84 : check_process_probe_kernel_support(systemtap_session& s)
4188 : : {
4189 : : // If we've got utrace, we're good to go.
4190 [ + - ][ + - ]: 84 : if (s.kernel_config["CONFIG_UTRACE"] == "y")
[ + - ][ + - ]
[ - + ]
4191 : 0 : return;
4192 : :
4193 : : // We don't have utrace. For process probes that aren't
4194 : : // uprobes-based, we just need the task_finder. The task_finder
4195 : : // needs CONFIG_TRACEPOINTS and specific tracepoints. There is a
4196 : : // specific autoconf test for its needs.
4197 : : //
4198 : : // We'll just require CONFIG_TRACEPOINTS here as a quick-and-dirty
4199 : : // approximation.
4200 [ + + ][ + - ]: 84 : if (! s.need_uprobes && s.kernel_config["CONFIG_TRACEPOINTS"] == "y")
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + + # #
# # ]
4201 : 82 : return;
4202 : :
4203 : : // For uprobes-based process probes, we need the task_finder plus
4204 : : // the builtin inode-uprobes.
4205 [ + - ][ + - ]: 8 : if (s.need_uprobes
[ - + ][ - + ]
4206 [ + - ][ + - ]: 4 : && s.kernel_config["CONFIG_TRACEPOINTS"] == "y"
[ + - ][ + - ]
[ + - ][ + - ]
[ # # # # ]
4207 [ + - ]: 2 : && kernel_supports_inode_uprobes(s))
4208 : 0 : return;
4209 : :
4210 [ + - ][ + - ]: 84 : throw semantic_error (_("process probes not available without kernel CONFIG_UTRACE or CONFIG_TRACEPOINTS/CONFIG_ARCH_SUPPORTS_UPROBES/CONFIG_UPROBES"));
4211 : : }
4212 : :
4213 : :
4214 : 330227 : dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
4215 : : const string& filename,
4216 : : int line,
4217 : : // module & section specify a relocation
4218 : : // base for <addr>, unless section==""
4219 : : // (equivalently module=="kernel")
4220 : : const string& module,
4221 : : const string& section,
4222 : : // NB: dwfl_addr is the virtualized
4223 : : // address for this symbol.
4224 : : Dwarf_Addr dwfl_addr,
4225 : : // addr is the section-offset for
4226 : : // actual relocation.
4227 : : Dwarf_Addr addr,
4228 : : dwarf_query& q,
4229 : : Dwarf_Die* scope_die /* may be null */)
4230 : : : derived_probe (q.base_probe, q.base_loc, true /* .components soon rewritten */ ),
4231 : : module (module), section (section), addr (addr),
4232 : : path (q.path),
4233 : : has_process (q.has_process),
4234 : : has_return (q.has_return),
4235 : : has_maxactive (q.has_maxactive),
4236 : : has_library (q.has_library),
4237 : : maxactive_val (q.maxactive_val),
4238 : : user_path (q.user_path),
4239 : : user_lib (q.user_lib),
4240 : : access_vars(false),
4241 : : saved_longs(0), saved_strings(0),
4242 [ + - ][ + - ]: 330227 : entry_handler(0)
[ + - ][ + - ]
[ + - ][ + - ]
4243 : : {
4244 [ + - ][ - + ]: 330227 : if (user_lib.size() != 0)
4245 : 0 : has_library = true;
4246 : :
4247 [ + + ]: 330227 : if (q.has_process)
4248 : : {
4249 : : // We may receive probes on two types of ELF objects: ET_EXEC or ET_DYN.
4250 : : // ET_EXEC ones need no further relocation on the addr(==dwfl_addr), whereas
4251 : : // ET_DYN ones do (addr += run-time mmap base address). We tell these apart
4252 : : // by the incoming section value (".absolute" vs. ".dynamic").
4253 : : // XXX Assert invariants here too?
4254 : :
4255 : : // inode-uprobes needs an offset rather than an absolute VM address.
4256 : : // ditto for userspace runtimes (dyninst)
4257 [ + - ][ + - ]: 11862 : if ((kernel_supports_inode_uprobes(q.dw.sess) || q.dw.sess.runtime_usermode_p()) &&
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ - + ]
4258 [ # # ]: 0 : section == ".absolute" && addr == dwfl_addr &&
4259 : : addr >= q.dw.module_start && addr < q.dw.module_end)
4260 : 0 : this->addr = addr - q.dw.module_start;
4261 : : }
4262 : : else
4263 : : {
4264 : : // Assert kernel relocation invariants
4265 [ + - ][ + + ]: 318365 : if (section == "" && dwfl_addr != addr) // addr should be absolute
[ - + ][ - + ]
4266 [ # # ][ # # ]: 0 : throw semantic_error (_("missing relocation basis"), tok);
4267 [ + - ][ + + ]: 318365 : if (section != "" && dwfl_addr == addr) // addr should be an offset
[ - + ][ - + ]
4268 [ # # ][ # # ]: 0 : throw semantic_error (_("inconsistent relocation address"), tok);
4269 : : }
4270 : :
4271 : : // XXX: hack for strange g++/gcc's
4272 : : #ifndef USHRT_MAX
4273 : : #define USHRT_MAX 32767
4274 : : #endif
4275 : :
4276 : : // Range limit maxactive() value
4277 [ + + ][ + + ]: 330227 : if (has_maxactive && (maxactive_val < 0 || maxactive_val > USHRT_MAX))
[ + + ]
4278 : 2 : throw semantic_error (_F("maxactive value out of range [0,%s]",
4279 [ + - ][ + - ]: 2 : lex_cast(USHRT_MAX).c_str()), q.base_loc->components.front()->tok);
[ + - ][ + - ]
[ + - ]
4280 : :
4281 : : // Expand target variables in the probe body
4282 [ + + ]: 330225 : if (!null_die(scope_die))
4283 : : {
4284 : : // XXX: user-space deref's for q.has_process!
4285 [ + - ]: 330173 : dwarf_var_expanding_visitor v (q, scope_die, dwfl_addr);
4286 [ + + ]: 330173 : v.replace (this->body);
4287 : :
4288 : : // Propagate perf.counters so we can emit later
4289 [ + - ]: 330167 : this->perf_counter_refs = v.perf_counter_refs;
4290 : : // Emit local var used to save the perf counter read value
4291 : 330167 : std::set<derived_probe*>::iterator pcii;
4292 [ + - ][ + + ]: 660340 : for (pcii = v.perf_counter_refs.begin();
4293 [ + - ]: 330170 : pcii != v.perf_counter_refs.end(); pcii++)
4294 : : {
4295 : 3 : map<string, pair<string,derived_probe*> >::iterator it;
4296 : : // Find the associated perf counter probe
4297 [ + - ][ + - ]: 6 : for (it=q.sess.perf_counters.begin() ;
4298 [ + - ]: 3 : it != q.sess.perf_counters.end();
4299 : : it++)
4300 [ + - ]: 3 : if ((*it).second.second == (*pcii))
4301 : 3 : break;
4302 [ + - ][ + - ]: 3 : vardecl* vd = new vardecl;
4303 [ + - ][ + - ]: 3 : vd->name = "__perf_read_" + (*it).first;
[ + - ]
4304 : 3 : vd->tok = this->tok;
4305 [ + - ]: 3 : vd->set_arity(0, this->tok);
4306 : 3 : vd->type = pe_long;
4307 : 3 : vd->synthetic = true;
4308 [ + - ]: 3 : this->locals.push_back (vd);
4309 : : }
4310 : :
4311 : :
4312 [ + + ]: 330167 : if (!q.has_process)
4313 : 318355 : access_vars = v.visited;
4314 : :
4315 : : // If during target-variable-expanding the probe, we added a new block
4316 : : // of code, add it to the start of the probe.
4317 [ + + ]: 330167 : if (v.add_block)
4318 [ + - ][ + - ]: 698 : this->body = new block(v.add_block, this->body);
4319 : :
4320 : : // If when target-variable-expanding the probe, we need to synthesize a
4321 : : // sibling function-entry probe. We don't go through the whole probe derivation
4322 : : // business (PR10642) that could lead to wildcard/alias resolution, or for that
4323 : : // dwarf-induced duplication.
4324 [ + + ]: 330167 : if (v.add_call_probe)
4325 : : {
4326 [ + - ][ - + ]: 1287 : assert (q.has_return && !q.has_call);
4327 : :
4328 : : // We temporarily replace q.base_probe.
4329 : 1287 : statement* old_body = q.base_probe->body;
4330 : 1287 : q.base_probe->body = v.add_call_probe;
4331 : 1287 : q.has_return = false;
4332 : 1287 : q.has_call = true;
4333 : :
4334 [ + + ]: 1287 : if (q.has_process)
4335 : : entry_handler = new uprobe_derived_probe (funcname, filename, line,
4336 : : module, section, dwfl_addr,
4337 [ + - ][ + - ]: 1 : addr, q, scope_die);
4338 : : else
4339 : : entry_handler = new dwarf_derived_probe (funcname, filename, line,
4340 : : module, section, dwfl_addr,
4341 [ + - ][ + - ]: 1286 : addr, q, scope_die);
4342 : :
4343 : 1287 : saved_longs = entry_handler->saved_longs = v.saved_longs;
4344 : 1287 : saved_strings = entry_handler->saved_strings = v.saved_strings;
4345 : :
4346 [ + - ]: 1287 : q.results.push_back (entry_handler);
4347 : :
4348 : 1287 : q.has_return = true;
4349 : 1287 : q.has_call = false;
4350 : 1287 : q.base_probe->body = old_body;
4351 : : }
4352 : : // Save the local variables for listing mode
4353 [ + + ]: 330167 : if (q.sess.listing_mode_vars)
4354 [ + - ][ + - ]: 330173 : saveargs(q, scope_die, dwfl_addr);
4355 : : }
4356 : : // else - null scope_die - $target variables will produce an error during translate phase
4357 : :
4358 : : // PR10820: null scope die, local variables aren't accessible, not necessary to invoke saveargs
4359 : :
4360 : : // Reset the sole element of the "locations" vector as a
4361 : : // "reverse-engineered" form of the incoming (q.base_loc) probe
4362 : : // point. This allows a user to see what function / file / line
4363 : : // number any particular match of the wildcards.
4364 : :
4365 [ + - ]: 330219 : vector<probe_point::component*> comps;
4366 [ + + ]: 330219 : if (q.has_kernel)
4367 [ + - ][ + - ]: 252452 : comps.push_back (new probe_point::component(TOK_KERNEL));
[ + - ]
4368 [ + + ]: 77767 : else if(q.has_module)
4369 [ + - ][ + - ]: 65907 : comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module)));
[ + - ][ + - ]
[ + - ]
4370 [ + - ]: 11860 : else if(q.has_process)
4371 [ + - ][ + - ]: 11860 : comps.push_back (new probe_point::component(TOK_PROCESS, new literal_string(module)));
[ + - ][ + - ]
[ + - ]
4372 : : else
4373 : 0 : assert (0);
4374 : :
4375 [ + - ]: 330219 : string fn_or_stmt;
4376 [ + + ][ - + ]: 330219 : if (q.has_function_str || q.has_function_num)
4377 [ + - ]: 330099 : fn_or_stmt = "function";
4378 : : else
4379 [ + - ]: 120 : fn_or_stmt = "statement";
4380 : :
4381 [ + + ][ + + ]: 330219 : if (q.has_function_str || q.has_statement_str)
4382 : : {
4383 [ + - ]: 330142 : string retro_name = funcname;
4384 [ + - ][ + + ]: 330142 : if (filename != "")
4385 : : {
4386 [ + - ][ + - ]: 330034 : retro_name += ("@" + string (filename));
[ + - ][ + - ]
[ + - ]
4387 [ + - ]: 330034 : if (line > 0)
4388 [ + - ][ + - ]: 330034 : retro_name += (":" + lex_cast (line));
[ + - ][ + - ]
[ + - ]
4389 : : }
4390 : : comps.push_back
4391 : : (new probe_point::component
4392 [ + - ][ + - ]: 330142 : (fn_or_stmt, new literal_string (retro_name)));
[ + - ][ + - ]
[ + - ][ + - ]
4393 : : }
4394 [ + - ][ + - ]: 77 : else if (q.has_function_num || q.has_statement_num)
4395 : : {
4396 : : Dwarf_Addr retro_addr;
4397 [ - + ]: 77 : if (q.has_function_num)
4398 : 0 : retro_addr = q.function_num_val;
4399 : : else
4400 : 77 : retro_addr = q.statement_num_val;
4401 : : comps.push_back (new probe_point::component
4402 : : (fn_or_stmt,
4403 [ + - ][ + - ]: 77 : new literal_number(retro_addr, true)));
[ + - ][ + - ]
[ + - ]
4404 : :
4405 [ + + ]: 77 : if (q.has_absolute)
4406 [ + - ][ + - ]: 4 : comps.push_back (new probe_point::component (TOK_ABSOLUTE));
[ + - ]
4407 : : }
4408 : :
4409 [ + + ]: 330219 : if (q.has_call)
4410 [ + - ][ + - ]: 69128 : comps.push_back (new probe_point::component(TOK_CALL));
[ + - ]
4411 [ + + ]: 330219 : if (q.has_exported)
4412 [ + - ][ + - ]: 9 : comps.push_back (new probe_point::component(TOK_EXPORTED));
[ + - ]
4413 [ + + ]: 330219 : if (q.has_inline)
4414 [ + - ][ + - ]: 85621 : comps.push_back (new probe_point::component(TOK_INLINE));
[ + - ]
4415 [ + + ]: 330219 : if (has_return)
4416 [ + - ][ + - ]: 46476 : comps.push_back (new probe_point::component(TOK_RETURN));
[ + - ]
4417 [ + + ]: 330219 : if (has_maxactive)
4418 : : comps.push_back (new probe_point::component
4419 [ + - ][ + - ]: 16 : (TOK_MAXACTIVE, new literal_number(maxactive_val)));
[ + - ][ + - ]
[ + - ]
4420 : :
4421 : : // Overwrite it.
4422 [ + - ][ + - ]: 330227 : this->sole_location()->components = comps;
[ + - ][ + - ]
4423 : 330227 : }
4424 : :
4425 : :
4426 : : void
4427 : 11777 : dwarf_derived_probe::saveargs(dwarf_query& q, Dwarf_Die* scope_die,
4428 : : Dwarf_Addr dwfl_addr)
4429 : : {
4430 [ + - ]: 11777 : if (null_die(scope_die))
4431 : 11777 : return;
4432 : :
4433 : 11777 : bool verbose = q.sess.verbose > 2;
4434 : :
4435 [ - + ]: 11777 : if (verbose)
4436 [ # # ][ # # ]: 0 : clog << _F("saveargs: examining '%s' (dieoffset: %#" PRIx64 ")\n", (dwarf_diename(scope_die)?: "unknown"), dwarf_dieoffset(scope_die));
[ # # ][ # # ]
[ # # ][ # # ]
4437 : :
4438 [ - + ]: 11777 : if (has_return)
4439 : : {
4440 : : /* Only save the return value if it has a type. */
4441 [ # # ]: 0 : string type_name;
4442 : : Dwarf_Die type_die;
4443 [ # # ][ # # ]: 0 : if (dwarf_attr_die (scope_die, DW_AT_type, &type_die) &&
[ # # ][ # # ]
4444 [ # # ]: 0 : dwarf_type_name(&type_die, type_name))
4445 [ # # ][ # # ]: 0 : args.push_back("$return:"+type_name);
[ # # ]
4446 : :
4447 [ # # ]: 0 : else if (verbose)
4448 [ # # ][ # # ]: 0 : clog << _F("saveargs: failed to retrieve type name for return value (dieoffset: %s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
4449 [ # # ][ # # ]: 0 : lex_cast_hex(dwarf_dieoffset(scope_die)).c_str());
4450 : : }
4451 : :
4452 : : Dwarf_Die arg;
4453 [ + - ]: 11777 : vector<Dwarf_Die> scopes = q.dw.getscopes(scope_die);
4454 [ + - ]: 23556 : for (unsigned i = 0; i < scopes.size(); ++i)
4455 : : {
4456 [ + - ][ + + ]: 23556 : if (dwarf_tag(&scopes[i]) == DW_TAG_compile_unit)
4457 : 11777 : break; // we don't want file-level variables
4458 [ + - ][ + + ]: 11779 : if (dwarf_child (&scopes[i], &arg) == 0)
4459 [ + + ]: 27887 : do
4460 : : {
4461 [ + - ][ + + ]: 27887 : switch (dwarf_tag (&arg))
4462 : : {
4463 : : case DW_TAG_variable:
4464 : : case DW_TAG_formal_parameter:
4465 : 21681 : break;
4466 : :
4467 : : default:
4468 : 6206 : continue;
4469 : : }
4470 : :
4471 : : /* Ignore this local if it has no name. */
4472 [ + - ]: 21681 : const char *arg_name = dwarf_diename (&arg);
4473 [ + + ]: 21681 : if (!arg_name)
4474 : : {
4475 [ - + ]: 948 : if (verbose)
4476 [ # # ][ # # ]: 0 : clog << _F("saveargs: failed to retrieve name for local (dieoffset: %s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
4477 [ # # ]: 0 : lex_cast_hex(dwarf_dieoffset(&arg)).c_str());
4478 : 948 : continue;
4479 : : }
4480 : :
4481 [ - + ]: 20733 : if (verbose)
4482 [ # # ][ # # ]: 0 : clog << _F("saveargs: finding location for local '%s' (dieoffset: %s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
4483 [ # # ]: 0 : arg_name, lex_cast_hex(dwarf_dieoffset(&arg)).c_str());
4484 : :
4485 : : /* Ignore this local if it has no location (or not at this PC). */
4486 : : /* NB: It still may not be directly accessible, e.g. if it is an
4487 : : * aggregate type, implicit_pointer, etc., but the user can later
4488 : : * figure out how to access the interesting parts. */
4489 : :
4490 : : /* XXX: Perhaps saveargs() / listings-mode should work by synthesizing
4491 : : * several synthetic
4492 : : * probe foo { $var }
4493 : : * probes, testing them for overall resolvability.
4494 : : */
4495 : :
4496 : : Dwarf_Attribute attr_mem;
4497 [ + - ][ + + ]: 20733 : if (!dwarf_attr_integrate (&arg, DW_AT_const_value, &attr_mem))
4498 : : {
4499 : : Dwarf_Op *expr;
4500 : : size_t len;
4501 [ + - ][ + + ]: 20731 : if (!dwarf_attr_integrate (&arg, DW_AT_location, &attr_mem))
4502 : : {
4503 [ - + ]: 44 : if (verbose)
4504 [ # # ][ # # ]: 0 : clog << _F("saveargs: failed to resolve the location for local '%s' (dieoffset: %s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
4505 [ # # ]: 0 : arg_name, lex_cast_hex(dwarf_dieoffset(&arg)).c_str());
4506 : 44 : continue;
4507 : : }
4508 [ + + ]: 20687 : else if (!(dwarf_getlocation_addr(&attr_mem, dwfl_addr, &expr,
4509 [ + - ][ + + ]: 20687 : &len, 1) == 1 && len > 0))
[ - + ]
4510 : : {
4511 [ + - ]: 164 : Dwarf_Addr dwfl_addr2 = q.dw.pr15123_retry_addr (dwfl_addr, & arg);
4512 [ - + ][ # # ]: 164 : if (!dwfl_addr2 || (!(dwarf_getlocation_addr(&attr_mem, dwfl_addr2, &expr,
[ + - ]
4513 [ # # ][ # # ]: 0 : &len, 1) == 1 && len > 0))) {
4514 [ - + ]: 164 : if (verbose)
4515 [ # # ][ # # ]: 0 : clog << _F("saveargs: local '%s' (dieoffset: %s) is not available at this address (%s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4516 [ # # ]: 0 : arg_name, lex_cast_hex(dwarf_dieoffset(&arg)).c_str(), lex_cast_hex(dwfl_addr).c_str());
4517 : 20731 : continue;
4518 : : }
4519 : : }
4520 : : }
4521 : :
4522 : : /* Ignore this local if it has no type. */
4523 [ + - ]: 20525 : string type_name;
4524 : : Dwarf_Die type_die;
4525 [ + - ][ + - ]: 41050 : if (!dwarf_attr_die (&arg, DW_AT_type, &type_die) ||
[ - + ][ - + ]
4526 [ + - ]: 20525 : !dwarf_type_name(&type_die, type_name))
4527 : : {
4528 [ # # ]: 0 : if (verbose)
4529 [ # # ][ # # ]: 0 : clog << _F("saveargs: failed to retrieve type name for local '%s' (dieoffset: %s)\n",
[ # # ][ # # ]
[ # # ][ # # ]
4530 [ # # ]: 0 : arg_name, lex_cast_hex(dwarf_dieoffset(&arg)).c_str());
4531 : 0 : continue;
4532 : : }
4533 : :
4534 : : /* This local looks good -- save it! */
4535 [ + - ][ + - ]: 27887 : args.push_back("$"+string(arg_name)+":"+type_name);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
4536 : : }
4537 [ + - ]: 27887 : while (dwarf_siblingof (&arg, &arg) == 0);
4538 [ + - ]: 11777 : }
4539 : : }
4540 : :
4541 : :
4542 : : void
4543 : 11825 : dwarf_derived_probe::getargs(std::list<std::string> &arg_set) const
4544 : : {
4545 : 11825 : arg_set.insert(arg_set.end(), args.begin(), args.end());
4546 : 11825 : }
4547 : :
4548 : :
4549 : : void
4550 : 6169 : dwarf_derived_probe::emit_privilege_assertion (translator_output* o)
4551 : : {
4552 [ - + ]: 6169 : if (has_process)
4553 : : {
4554 : : // These probes are allowed for unprivileged users, but only in the
4555 : : // context of processes which they own.
4556 : 0 : emit_process_owner_assertion (o);
4557 : 6169 : return;
4558 : : }
4559 : :
4560 : : // Other probes must contain the default assertion which aborts
4561 : : // if executed by an unprivileged user.
4562 : 6169 : derived_probe::emit_privilege_assertion (o);
4563 : : }
4564 : :
4565 : :
4566 : : void
4567 : 25760 : dwarf_derived_probe::print_dupe_stamp(ostream& o)
4568 : : {
4569 [ - + ]: 25760 : if (has_process)
4570 : : {
4571 : : // These probes are allowed for unprivileged users, but only in the
4572 : : // context of processes which they own.
4573 : 0 : print_dupe_stamp_unprivileged_process_owner (o);
4574 : 25760 : return;
4575 : : }
4576 : :
4577 : : // Other probes must contain the default dupe stamp
4578 : 25760 : derived_probe::print_dupe_stamp (o);
4579 : : }
4580 : :
4581 : :
4582 : : void
4583 : 14616 : dwarf_derived_probe::register_statement_variants(match_node * root,
4584 : : dwarf_builder * dw,
4585 : : privilege_t privilege)
4586 : : {
4587 : : root
4588 : : ->bind_privilege(privilege)
4589 : 14616 : ->bind(dw);
4590 : 14616 : }
4591 : :
4592 : : void
4593 : 14616 : dwarf_derived_probe::register_function_variants(match_node * root,
4594 : : dwarf_builder * dw,
4595 : : privilege_t privilege)
4596 : : {
4597 : : root
4598 : : ->bind_privilege(privilege)
4599 : 14616 : ->bind(dw);
4600 : : root->bind(TOK_CALL)
4601 : : ->bind_privilege(privilege)
4602 : 14616 : ->bind(dw);
4603 : : root->bind(TOK_EXPORTED)
4604 : : ->bind_privilege(privilege)
4605 : 14616 : ->bind(dw);
4606 : : root->bind(TOK_RETURN)
4607 : : ->bind_privilege(privilege)
4608 : 14616 : ->bind(dw);
4609 : :
4610 : : // For process probes / uprobes, .maxactive() is unused.
4611 [ + + ]: 14616 : if (! pr_contains (privilege, pr_stapusr))
4612 : : {
4613 : : root->bind(TOK_RETURN)
4614 : 4872 : ->bind_num(TOK_MAXACTIVE)->bind(dw);
4615 : : }
4616 : 14616 : }
4617 : :
4618 : : void
4619 : 7308 : dwarf_derived_probe::register_function_and_statement_variants(
4620 : : systemtap_session& s,
4621 : : match_node * root,
4622 : : dwarf_builder * dw,
4623 : : privilege_t privilege
4624 : : )
4625 : : {
4626 : : // Here we match 4 forms:
4627 : : //
4628 : : // .function("foo")
4629 : : // .function(0xdeadbeef)
4630 : : // .statement("foo")
4631 : : // .statement(0xdeadbeef)
4632 : :
4633 : 7308 : match_node *fv_root = root->bind_str(TOK_FUNCTION);
4634 : 7308 : register_function_variants(fv_root, dw, privilege);
4635 : : // ROOT.function("STRING") always gets the .inline and .label variants.
4636 : : fv_root->bind(TOK_INLINE)
4637 : : ->bind_privilege(privilege)
4638 : 7308 : ->bind(dw);
4639 : : fv_root->bind_str(TOK_LABEL)
4640 : : ->bind_privilege(privilege)
4641 : 7308 : ->bind(dw);
4642 : :
4643 : 7308 : fv_root = root->bind_num(TOK_FUNCTION);
4644 : 7308 : register_function_variants(fv_root, dw, privilege);
4645 : : // ROOT.function(NUMBER).inline is deprecated in release 1.7 and removed thereafter.
4646 [ + + ]: 7308 : if (strverscmp(s.compatible.c_str(), "1.7") <= 0)
4647 : : {
4648 : : fv_root->bind(TOK_INLINE)
4649 : : ->bind_privilege(privilege)
4650 : 42 : ->bind(dw);
4651 : : }
4652 : :
4653 : 7308 : register_statement_variants(root->bind_str(TOK_STATEMENT), dw, privilege);
4654 : 7308 : register_statement_variants(root->bind_num(TOK_STATEMENT), dw, privilege);
4655 : 7308 : }
4656 : :
4657 : : void
4658 : 4872 : dwarf_derived_probe::register_sdt_variants(systemtap_session& s,
4659 : : match_node * root,
4660 : : dwarf_builder * dw)
4661 : : {
4662 : : root->bind_str(TOK_MARK)
4663 : : ->bind_privilege(pr_all)
4664 : 4872 : ->bind(dw);
4665 : : root->bind_str(TOK_PROVIDER)->bind_str(TOK_MARK)
4666 : : ->bind_privilege(pr_all)
4667 : 4872 : ->bind(dw);
4668 : 4872 : }
4669 : :
4670 : : void
4671 : 4872 : dwarf_derived_probe::register_plt_variants(systemtap_session& s,
4672 : : match_node * root,
4673 : : dwarf_builder * dw)
4674 : : {
4675 : : root->bind(TOK_PLT)
4676 : : ->bind_privilege(pr_all)
4677 : 4872 : ->bind(dw);
4678 : : root->bind_str(TOK_PLT)
4679 : : ->bind_privilege(pr_all)
4680 : 4872 : ->bind(dw);
4681 : : root->bind(TOK_PLT)->bind_num(TOK_STATEMENT)
4682 : : ->bind_privilege(pr_all)
4683 : 4872 : ->bind(dw);
4684 : : root->bind_str(TOK_PLT)->bind_num(TOK_STATEMENT)
4685 : : ->bind_privilege(pr_all)
4686 : 4872 : ->bind(dw);
4687 : 4872 : }
4688 : :
4689 : : void
4690 : 1218 : dwarf_derived_probe::register_patterns(systemtap_session& s)
4691 : : {
4692 : 1218 : match_node* root = s.pattern_root;
4693 [ + - ][ + - ]: 1218 : dwarf_builder *dw = new dwarf_builder();
4694 : :
4695 [ + - ][ + - ]: 1218 : update_visitor *filter = new dwarf_cast_expanding_visitor(s, *dw);
4696 [ + - ]: 1218 : s.code_filters.push_back(filter);
4697 : :
4698 [ + - ][ + - ]: 1218 : register_function_and_statement_variants(s, root->bind(TOK_KERNEL), dw, pr_privileged);
4699 [ + - ][ + - ]: 1218 : register_function_and_statement_variants(s, root->bind_str(TOK_MODULE), dw, pr_privileged);
4700 : : root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
4701 [ + - ][ + - ]: 1218 : ->bind(dw);
[ + - ][ + - ]
4702 : :
4703 : : match_node* uprobes[] = {
4704 [ + - ]: 1218 : root->bind(TOK_PROCESS),
4705 [ + - ]: 1218 : root->bind_str(TOK_PROCESS),
4706 [ + - ][ + - ]: 1218 : root->bind(TOK_PROCESS)->bind_str(TOK_LIBRARY),
4707 [ + - ][ + - ]: 1218 : root->bind_str(TOK_PROCESS)->bind_str(TOK_LIBRARY),
4708 : 4872 : };
4709 [ + + ]: 6090 : for (size_t i = 0; i < sizeof(uprobes) / sizeof(*uprobes); ++i)
4710 : : {
4711 [ + - ]: 4872 : register_function_and_statement_variants(s, uprobes[i], dw, pr_all);
4712 [ + - ]: 4872 : register_sdt_variants(s, uprobes[i], dw);
4713 [ + - ]: 4872 : register_plt_variants(s, uprobes[i], dw);
4714 : : }
4715 : 1218 : }
4716 : :
4717 : : void
4718 : 6175 : dwarf_derived_probe::emit_probe_local_init(systemtap_session& s, translator_output * o)
4719 : : {
4720 : 6175 : std::set<derived_probe*>::iterator pcii;
4721 [ + - ][ + + ]: 12352 : for (pcii = perf_counter_refs.begin();
4722 [ + - ]: 6176 : pcii != perf_counter_refs.end();
4723 : : pcii++)
4724 : : {
4725 : 1 : map<string, pair<string,derived_probe*> >::iterator it;
4726 : : // Find the associated perf.counter probe
4727 : 1 : unsigned i = 0;
4728 [ + - ][ + - ]: 2 : for (it=s.perf_counters.begin() ;
4729 [ + - ]: 1 : it != s.perf_counters.end();
4730 : : it++, i++)
4731 [ + - ]: 1 : if ((*it).second.second == (*pcii))
4732 : 1 : break;
4733 : : // place the perf counter read so it precedes stp_lock_probe
4734 [ + - ]: 1 : o->newline() << "l->l___perf_read_" + (*it).first
4735 : : + " = (((int64_t) (_stp_perf_read(smp_processor_id(),"
4736 [ + - ][ + - ]: 1 : + lex_cast(i) + "))));";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
4737 : : }
4738 : :
4739 [ + + ]: 6175 : if (access_vars)
4740 : : {
4741 : : // if accessing $variables, emit bsp cache setup for speeding up
4742 [ + - ][ + - ]: 5161 : o->newline() << "#if defined __ia64__";
4743 [ + - ][ + - ]: 5161 : o->newline() << "bspcache(c->unwaddr, c->kregs);";
4744 [ + - ][ + - ]: 5161 : o->newline() << "#endif";
4745 : : }
4746 : 6175 : }
4747 : :
4748 : : // ------------------------------------------------------------------------
4749 : :
4750 : : void
4751 : 317756 : dwarf_derived_probe_group::enroll (dwarf_derived_probe* p)
4752 : : {
4753 [ + - ][ + - ]: 317756 : probes_by_module.insert (make_pair (p->module, p));
[ + - ][ + - ]
[ + - ]
4754 : :
4755 : : // XXX: probes put at the same address should all share a
4756 : : // single kprobe/kretprobe, and have their handlers executed
4757 : : // sequentially.
4758 : 317756 : }
4759 : :
4760 : : void
4761 : 207 : dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
4762 : : {
4763 [ + - ][ + - ]: 414 : if (probes_by_module.empty()) return;
4764 : :
4765 [ + - ][ + - ]: 207 : s.op->newline() << "/* ---- dwarf probes ---- */";
4766 : :
4767 : : // Warn of misconfigured kernels
4768 [ + - ][ + - ]: 207 : s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
4769 [ + - ][ + - ]: 207 : s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
4770 [ + - ][ + - ]: 207 : s.op->newline() << "#endif";
4771 [ + - ]: 207 : s.op->newline();
4772 : :
4773 [ + - ][ + - ]: 207 : s.op->newline() << "#ifndef KRETACTIVE";
4774 [ + - ][ + - ]: 207 : s.op->newline() << "#define KRETACTIVE (max(15,6*(int)num_possible_cpus()))";
4775 [ + - ][ + - ]: 207 : s.op->newline() << "#endif";
4776 : :
4777 : : // Forward decls
4778 [ + - ][ + - ]: 207 : s.op->newline() << "#include \"linux/kprobes-common.h\"";
4779 : :
4780 : : // Forward declare the master entry functions
4781 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
4782 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs);";
4783 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
4784 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs);";
4785 : :
4786 : : // Emit an array of kprobe/kretprobe pointers
4787 [ + - ][ + - ]: 207 : s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
4788 [ + - ][ + - ]: 207 : s.op->newline() << "static void * stap_unreg_kprobes[" << probes_by_module.size() << "];";
[ + - ][ + - ]
[ + - ]
4789 [ + - ][ + - ]: 207 : s.op->newline() << "#endif";
4790 : :
4791 : : // Emit the actual probe list.
4792 : :
4793 : : // NB: we used to plop a union { struct kprobe; struct kretprobe } into
4794 : : // struct stap_dwarf_probe, but it being initialized data makes it add
4795 : : // hundreds of bytes of padding per stap_dwarf_probe. (PR5673)
4796 [ + - ][ + - ]: 207 : s.op->newline() << "static struct stap_dwarf_kprobe stap_dwarf_kprobes[" << probes_by_module.size() << "];";
[ + - ][ + - ]
[ + - ]
4797 : : // NB: bss!
4798 : :
4799 [ + - ][ + - ]: 207 : s.op->newline() << "static struct stap_dwarf_probe {";
4800 [ + - ][ + - ]: 207 : s.op->newline(1) << "const unsigned return_p:1;";
4801 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned maxactive_p:1;";
4802 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned optional_p:1;";
4803 [ + - ][ + - ]: 207 : s.op->newline() << "unsigned registered_p:1;";
4804 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned short maxactive_val;";
4805 : :
4806 : : // data saved in the kretprobe_instance packet
4807 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned short saved_longs;";
4808 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned short saved_strings;";
4809 : :
4810 : : // Let's find some stats for the embedded strings. Maybe they
4811 : : // are small and uniform enough to justify putting char[MAX]'s into
4812 : : // the array instead of relocated char*'s.
4813 : 207 : size_t module_name_max = 0, section_name_max = 0;
4814 : 207 : size_t module_name_tot = 0, section_name_tot = 0;
4815 [ + - ]: 207 : size_t all_name_cnt = probes_by_module.size(); // for average
4816 [ + - ][ + - ]: 12879 : for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
[ + + ]
4817 : : {
4818 [ + - ]: 12672 : dwarf_derived_probe* p = it->second;
4819 : : #define DOIT(var,expr) do { \
4820 : : size_t var##_size = (expr) + 1; \
4821 : : var##_max = max (var##_max, var##_size); \
4822 : : var##_tot += var##_size; } while (0)
4823 [ + - ]: 12672 : DOIT(module_name, p->module.size());
4824 [ + - ]: 12672 : DOIT(section_name, p->section.size());
4825 : : #undef DOIT
4826 : : }
4827 : :
4828 : : // Decide whether it's worthwhile to use char[] or char* by comparing
4829 : : // the amount of average waste (max - avg) to the relocation data size
4830 : : // (3 native long words).
4831 : : #define CALCIT(var) \
4832 : : if ((var##_name_max-(var##_name_tot/all_name_cnt)) < (3 * sizeof(void*))) \
4833 : : { \
4834 : : s.op->newline() << "const char " << #var << "[" << var##_name_max << "];"; \
4835 : : if (s.verbose > 2) clog << "stap_dwarf_probe " << #var \
4836 : : << "[" << var##_name_max << "]" << endl; \
4837 : : } \
4838 : : else \
4839 : : { \
4840 : : s.op->newline() << "const char * const " << #var << ";"; \
4841 : : if (s.verbose > 2) clog << "stap_dwarf_probe *" << #var << endl; \
4842 : : }
4843 : :
4844 [ + - ][ + - ]: 207 : CALCIT(module);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4845 [ + - ][ + - ]: 207 : CALCIT(section);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
4846 : : #undef CALCIT
4847 : :
4848 [ + - ][ + - ]: 207 : s.op->newline() << "const unsigned long address;";
4849 [ + - ][ + - ]: 207 : s.op->newline() << "const struct stap_probe * const probe;";
4850 [ + - ][ + - ]: 207 : s.op->newline() << "const struct stap_probe * const entry_probe;";
4851 [ + - ][ + - ]: 207 : s.op->newline(-1) << "} stap_dwarf_probes[] = {";
4852 [ + - ]: 207 : s.op->indent(1);
4853 : :
4854 [ + - ][ + - ]: 12879 : for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
[ + + ]
4855 : : {
4856 [ + - ]: 12672 : dwarf_derived_probe* p = it->second;
4857 [ + - ][ + - ]: 12672 : s.op->newline() << "{";
4858 [ + + ]: 12672 : if (p->has_return)
4859 [ + - ][ + - ]: 4082 : s.op->line() << " .return_p=1,";
4860 [ + + ]: 12672 : if (p->has_maxactive)
4861 : : {
4862 [ + - ][ + - ]: 13 : s.op->line() << " .maxactive_p=1,";
4863 [ + - ][ - + ]: 13 : assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
4864 [ + - ][ + - ]: 13 : s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
[ + - ][ + - ]
4865 : : }
4866 [ + + ][ - + ]: 12672 : if (p->saved_longs || p->saved_strings)
4867 : : {
4868 [ + - ]: 208 : if (p->saved_longs)
4869 [ + - ][ + - ]: 208 : s.op->line() << " .saved_longs=" << p->saved_longs << ",";
[ + - ][ + - ]
4870 [ + + ]: 208 : if (p->saved_strings)
4871 [ + - ][ + - ]: 1 : s.op->line() << " .saved_strings=" << p->saved_strings << ",";
[ + - ][ + - ]
4872 [ + - ]: 208 : if (p->entry_handler)
4873 [ + - ][ + - ]: 208 : s.op->line() << " .entry_probe=" << common_probe_init (p->entry_handler) << ",";
[ + - ][ + - ]
[ + - ][ + - ]
4874 : : }
4875 [ + + ]: 12672 : if (p->locations[0]->optional)
4876 [ + - ][ + - ]: 4089 : s.op->line() << " .optional_p=1,";
4877 [ + - ][ + - ]: 12672 : s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
[ + - ][ + - ]
[ + - ][ + - ]
4878 [ + - ][ + - ]: 12672 : s.op->line() << " .module=\"" << p->module << "\",";
[ + - ][ + - ]
4879 [ + - ][ + - ]: 12672 : s.op->line() << " .section=\"" << p->section << "\",";
[ + - ][ + - ]
4880 [ + - ][ + - ]: 12672 : s.op->line() << " .probe=" << common_probe_init (p) << ",";
[ + - ][ + - ]
[ + - ][ + - ]
4881 [ + - ][ + - ]: 12672 : s.op->line() << " },";
4882 : : }
4883 : :
4884 [ + - ][ + - ]: 207 : s.op->newline(-1) << "};";
4885 : :
4886 : : // Emit the kprobes callback function
4887 [ + - ]: 207 : s.op->newline();
4888 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
4889 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs) {";
4890 : : // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
4891 [ + - ][ + - ]: 207 : s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
4892 : : // Check that the index is plausible
4893 [ + - ][ + - ]: 207 : s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
4894 [ + - ][ + - ]: 207 : s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
[ + - ][ + - ]
[ + - ]
4895 [ + - ][ + - ]: 207 : s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4896 : : // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4897 [ + - ][ + - ]: 207 : s.op->line() << "];";
4898 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sdp->probe",
4899 [ + - ][ + - ]: 207 : "stp_probe_type_kprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
4900 [ + - ][ + - ]: 207 : s.op->newline() << "c->kregs = regs;";
4901 : :
4902 : : // Make it look like the IP is set as it wouldn't have been replaced
4903 : : // by a breakpoint instruction when calling real probe handler. Reset
4904 : : // IP regs on return, so we don't confuse kprobes. PR10458
4905 [ + - ][ + - ]: 207 : s.op->newline() << "{";
4906 [ + - ]: 207 : s.op->indent(1);
4907 [ + - ][ + - ]: 207 : s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->kregs);";
4908 [ + - ][ + - ]: 207 : s.op->newline() << "SET_REG_IP(regs, (unsigned long) inst->addr);";
4909 [ + - ][ + - ]: 207 : s.op->newline() << "(*sdp->probe->ph) (c);";
4910 [ + - ][ + - ]: 207 : s.op->newline() << "SET_REG_IP(regs, kprobes_ip);";
4911 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4912 : :
4913 [ + - ]: 207 : common_probe_entryfn_epilogue (s, true);
4914 [ + - ][ + - ]: 207 : s.op->newline() << "return 0;";
4915 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4916 : :
4917 : : // Same for kretprobes
4918 [ + - ]: 207 : s.op->newline();
4919 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kretprobe_common (struct kretprobe_instance *inst,";
4920 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs, int entry) {";
4921 [ + - ][ + - ]: 207 : s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
4922 : :
4923 : : // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
4924 [ + - ][ + - ]: 207 : s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
4925 : : // Check that the index is plausible
4926 [ + - ][ + - ]: 207 : s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
4927 [ + - ][ + - ]: 207 : s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
[ + - ][ + - ]
[ + - ]
4928 [ + - ][ + - ]: 207 : s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
4929 : : // XXX: it would be nice to give a more verbose error though; BUG_ON later?
4930 [ + - ][ + - ]: 207 : s.op->line() << "];";
4931 : :
4932 [ + - ][ + - ]: 207 : s.op->newline() << "const struct stap_probe *sp = entry ? sdp->entry_probe : sdp->probe;";
4933 [ + - ][ + - ]: 207 : s.op->newline() << "if (sp) {";
4934 [ + - ]: 207 : s.op->indent(1);
4935 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sp",
4936 [ + - ][ + - ]: 207 : "stp_probe_type_kretprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
4937 [ + - ][ + - ]: 207 : s.op->newline() << "c->kregs = regs;";
4938 : :
4939 : : // for assisting runtime's backtrace logic and accessing kretprobe data packets
4940 [ + - ][ + - ]: 207 : s.op->newline() << "c->ips.krp.pi = inst;";
4941 [ + - ][ + - ]: 207 : s.op->newline() << "c->ips.krp.pi_longs = sdp->saved_longs;";
4942 : :
4943 : : // Make it look like the IP is set as it wouldn't have been replaced
4944 : : // by a breakpoint instruction when calling real probe handler. Reset
4945 : : // IP regs on return, so we don't confuse kprobes. PR10458
4946 [ + - ][ + - ]: 207 : s.op->newline() << "{";
4947 [ + - ][ + - ]: 207 : s.op->newline(1) << "unsigned long kprobes_ip = REG_IP(c->kregs);";
4948 [ + - ][ + - ]: 207 : s.op->newline() << "if (entry)";
4949 [ + - ][ + - ]: 207 : s.op->newline(1) << "SET_REG_IP(regs, (unsigned long) inst->rp->kp.addr);";
4950 [ + - ][ + - ]: 207 : s.op->newline(-1) << "else";
4951 [ + - ][ + - ]: 207 : s.op->newline(1) << "SET_REG_IP(regs, (unsigned long)inst->ret_addr);";
4952 [ + - ][ + - ]: 207 : s.op->newline(-1) << "(sp->ph) (c);";
4953 [ + - ][ + - ]: 207 : s.op->newline() << "SET_REG_IP(regs, kprobes_ip);";
4954 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4955 : :
4956 [ + - ]: 207 : common_probe_entryfn_epilogue (s, true);
4957 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4958 [ + - ][ + - ]: 207 : s.op->newline() << "return 0;";
4959 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4960 : :
4961 [ + - ]: 207 : s.op->newline();
4962 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
4963 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs) {";
4964 [ + - ][ + - ]: 207 : s.op->newline(1) << "return enter_kretprobe_common(inst, regs, 0);";
4965 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4966 : :
4967 [ + - ]: 207 : s.op->newline();
4968 [ + - ][ + - ]: 207 : s.op->newline() << "static int enter_kretprobe_entry_probe (struct kretprobe_instance *inst,";
4969 [ + - ][ + - ]: 207 : s.op->line() << " struct pt_regs *regs) {";
4970 [ + - ][ + - ]: 207 : s.op->newline(1) << "return enter_kretprobe_common(inst, regs, 1);";
4971 [ + - ][ + - ]: 207 : s.op->newline(-1) << "}";
4972 : :
4973 [ + - ]: 207 : s.op->newline();
4974 : : }
4975 : :
4976 : :
4977 : : void
4978 : 207 : dwarf_derived_probe_group::emit_module_init (systemtap_session& s)
4979 : : {
4980 : 207 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
4981 : 207 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
4982 : 207 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
4983 : 207 : s.op->newline() << "unsigned long relocated_addr = _stp_kmodule_relocate (sdp->module, sdp->section, sdp->address);";
4984 : 207 : s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent
4985 : 207 : s.op->newline() << "probe_point = sdp->probe->pp;"; // for error messages
4986 : 207 : s.op->newline() << "if (sdp->return_p) {";
4987 : 207 : s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;";
4988 : 207 : s.op->newline() << "if (sdp->maxactive_p) {";
4989 : 207 : s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
4990 : 207 : s.op->newline(-1) << "} else {";
4991 : 207 : s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;";
4992 : 207 : s.op->newline(-1) << "}";
4993 : 207 : s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
4994 : 207 : s.op->newline() << "#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)";
4995 : 207 : s.op->newline() << "if (sdp->entry_probe) {";
4996 : 207 : s.op->newline(1) << "kp->u.krp.entry_handler = &enter_kretprobe_entry_probe;";
4997 : 207 : s.op->newline() << "kp->u.krp.data_size = sdp->saved_longs * sizeof(int64_t) + ";
4998 : 207 : s.op->newline() << " sdp->saved_strings * MAXSTRINGLEN;";
4999 : 207 : s.op->newline(-1) << "}";
5000 : 207 : s.op->newline() << "#endif";
5001 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
5002 : 207 : s.op->newline() << "#ifdef __ia64__";
5003 : 207 : s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;";
5004 : 207 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
5005 : 207 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5006 : 207 : s.op->newline() << "if (rc == 0) {";
5007 : 207 : s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);";
5008 : 207 : s.op->newline() << "if (rc != 0)";
5009 : 207 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5010 : 207 : s.op->newline(-2) << "}";
5011 : 207 : s.op->newline() << "#else";
5012 : 207 : s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
5013 : 207 : s.op->newline() << "#endif";
5014 : 207 : s.op->newline(-1) << "} else {";
5015 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
5016 : 207 : s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
5017 : 207 : s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
5018 : 207 : s.op->newline() << "#ifdef __ia64__";
5019 : 207 : s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
5020 : 207 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
5021 : 207 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5022 : 207 : s.op->newline() << "if (rc == 0) {";
5023 : 207 : s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);";
5024 : 207 : s.op->newline() << "if (rc != 0)";
5025 : 207 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5026 : 207 : s.op->newline(-2) << "}";
5027 : 207 : s.op->newline() << "#else";
5028 : 207 : s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
5029 : 207 : s.op->newline() << "#endif";
5030 : 207 : s.op->newline(-1) << "}";
5031 : 207 : s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
5032 : 207 : s.op->newline(1) << "sdp->registered_p = 0;";
5033 : 207 : s.op->newline() << "if (!sdp->optional_p)";
5034 : 207 : s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, (unsigned long) relocated_addr, rc);";
5035 : 207 : s.op->newline(-1) << "rc = 0;"; // continue with other probes
5036 : : // XXX: shall we increment numskipped?
5037 : 207 : s.op->newline(-1) << "}";
5038 : :
5039 : : #if 0 /* pre PR 6749; XXX consider making an option */
5040 : : s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
5041 : : s.op->newline(1) << "struct stap_dwarf_probe *sdp2 = & stap_dwarf_probes[j];";
5042 : : s.op->newline() << "struct stap_dwarf_kprobe *kp2 = & stap_dwarf_kprobes[j];";
5043 : : s.op->newline() << "if (sdp2->return_p) unregister_kretprobe (&kp2->u.krp);";
5044 : : s.op->newline() << "else unregister_kprobe (&kp2->u.kp);";
5045 : : s.op->newline() << "#ifdef __ia64__";
5046 : : s.op->newline() << "unregister_kprobe (&kp2->dummy);";
5047 : : s.op->newline() << "#endif";
5048 : : // NB: we don't have to clear sdp2->registered_p, since the module_exit code is
5049 : : // not run for this early-abort case.
5050 : : s.op->newline(-1) << "}";
5051 : : s.op->newline() << "break;"; // don't attempt to register any more probes
5052 : : s.op->newline(-1) << "}";
5053 : : #endif
5054 : :
5055 : 207 : s.op->newline() << "else sdp->registered_p = 1;";
5056 : 207 : s.op->newline(-1) << "}"; // for loop
5057 : 207 : }
5058 : :
5059 : :
5060 : : void
5061 : 207 : dwarf_derived_probe_group::emit_module_refresh (systemtap_session& s)
5062 : : {
5063 : 207 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5064 : 207 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
5065 : 207 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
5066 : 207 : s.op->newline() << "unsigned long relocated_addr = _stp_kmodule_relocate (sdp->module, sdp->section, sdp->address);";
5067 : 207 : s.op->newline() << "int rc;";
5068 : :
5069 : : // new module arrived?
5070 : 207 : s.op->newline() << "if (sdp->registered_p == 0 && relocated_addr != 0) {";
5071 : 207 : s.op->newline(1) << "if (sdp->return_p) {";
5072 : 207 : s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;";
5073 : 207 : s.op->newline() << "if (sdp->maxactive_p) {";
5074 : 207 : s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
5075 : 207 : s.op->newline(-1) << "} else {";
5076 : 207 : s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;";
5077 : 207 : s.op->newline(-1) << "}";
5078 : 207 : s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
5079 : 207 : s.op->newline() << "#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)";
5080 : 207 : s.op->newline() << "if (sdp->entry_probe) {";
5081 : 207 : s.op->newline(1) << "kp->u.krp.entry_handler = &enter_kretprobe_entry_probe;";
5082 : 207 : s.op->newline() << "kp->u.krp.data_size = sdp->saved_longs * sizeof(int64_t) + ";
5083 : 207 : s.op->newline() << " sdp->saved_strings * MAXSTRINGLEN;";
5084 : 207 : s.op->newline(-1) << "}";
5085 : 207 : s.op->newline() << "#endif";
5086 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
5087 : 207 : s.op->newline() << "#ifdef __ia64__";
5088 : 207 : s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;";
5089 : 207 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
5090 : 207 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5091 : 207 : s.op->newline() << "if (rc == 0) {";
5092 : 207 : s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);";
5093 : 207 : s.op->newline() << "if (rc != 0)";
5094 : 207 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5095 : 207 : s.op->newline(-2) << "}";
5096 : 207 : s.op->newline() << "#else";
5097 : 207 : s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
5098 : 207 : s.op->newline() << "#endif";
5099 : 207 : s.op->newline(-1) << "} else {";
5100 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
5101 : 207 : s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
5102 : 207 : s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
5103 : 207 : s.op->newline() << "#ifdef __ia64__";
5104 : 207 : s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
5105 : 207 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
5106 : 207 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
5107 : 207 : s.op->newline() << "if (rc == 0) {";
5108 : 207 : s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);";
5109 : 207 : s.op->newline() << "if (rc != 0)";
5110 : 207 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
5111 : 207 : s.op->newline(-2) << "}";
5112 : 207 : s.op->newline() << "#else";
5113 : 207 : s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
5114 : 207 : s.op->newline() << "#endif";
5115 : 207 : s.op->newline(-1) << "}";
5116 : 207 : s.op->newline() << "if (rc == 0) sdp->registered_p = 1;";
5117 : :
5118 : : // old module disappeared?
5119 : 207 : s.op->newline(-1) << "} else if (sdp->registered_p == 1 && relocated_addr == 0) {";
5120 : 207 : s.op->newline(1) << "if (sdp->return_p) {";
5121 : 207 : s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
5122 : 207 : s.op->newline() << "atomic_add (kp->u.krp.nmissed, skipped_count());";
5123 : 207 : s.op->newline() << "#ifdef STP_TIMING";
5124 : 207 : s.op->newline() << "if (kp->u.krp.nmissed)";
5125 : 207 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->probe->pp, kp->u.krp.nmissed);";
5126 : 207 : s.op->newline(-1) << "#endif";
5127 : 207 : s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, skipped_count());";
5128 : 207 : s.op->newline() << "#ifdef STP_TIMING";
5129 : 207 : s.op->newline() << "if (kp->u.krp.kp.nmissed)";
5130 : 207 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->probe->pp, kp->u.krp.kp.nmissed);";
5131 : 207 : s.op->newline(-1) << "#endif";
5132 : 207 : s.op->newline(-1) << "} else {";
5133 : 207 : s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
5134 : 207 : s.op->newline() << "atomic_add (kp->u.kp.nmissed, skipped_count());";
5135 : 207 : s.op->newline() << "#ifdef STP_TIMING";
5136 : 207 : s.op->newline() << "if (kp->u.kp.nmissed)";
5137 : 207 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->probe->pp, kp->u.kp.nmissed);";
5138 : 207 : s.op->newline(-1) << "#endif";
5139 : 207 : s.op->newline(-1) << "}";
5140 : 207 : s.op->newline() << "#if defined(__ia64__)";
5141 : 207 : s.op->newline() << "unregister_kprobe (&kp->dummy);";
5142 : 207 : s.op->newline() << "#endif";
5143 : 207 : s.op->newline() << "sdp->registered_p = 0;";
5144 : 207 : s.op->newline(-1) << "}";
5145 : :
5146 : 207 : s.op->newline(-1) << "}"; // for loop
5147 : 207 : }
5148 : :
5149 : :
5150 : :
5151 : :
5152 : : void
5153 : 284 : dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
5154 : : {
5155 : : //Unregister kprobes by batch interfaces.
5156 : 284 : s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
5157 : 284 : s.op->newline() << "j = 0;";
5158 : 284 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5159 : 284 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
5160 : 284 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
5161 : 284 : s.op->newline() << "if (! sdp->registered_p) continue;";
5162 : 284 : s.op->newline() << "if (!sdp->return_p)";
5163 : 284 : s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.kp;";
5164 : 284 : s.op->newline(-2) << "}";
5165 : 284 : s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
5166 : 284 : s.op->newline() << "j = 0;";
5167 : 284 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5168 : 284 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
5169 : 284 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
5170 : 284 : s.op->newline() << "if (! sdp->registered_p) continue;";
5171 : 284 : s.op->newline() << "if (sdp->return_p)";
5172 : 284 : s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.krp;";
5173 : 284 : s.op->newline(-2) << "}";
5174 : 284 : s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, j);";
5175 : 284 : s.op->newline() << "#ifdef __ia64__";
5176 : 284 : s.op->newline() << "j = 0;";
5177 : 284 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5178 : 284 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
5179 : 284 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
5180 : 284 : s.op->newline() << "if (! sdp->registered_p) continue;";
5181 : 284 : s.op->newline() << "stap_unreg_kprobes[j++] = &kp->dummy;";
5182 : 284 : s.op->newline(-1) << "}";
5183 : 284 : s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
5184 : 284 : s.op->newline() << "#endif";
5185 : 284 : s.op->newline() << "#endif";
5186 : :
5187 : 284 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
5188 : 284 : s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
5189 : 284 : s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
5190 : 284 : s.op->newline() << "if (! sdp->registered_p) continue;";
5191 : 284 : s.op->newline() << "if (sdp->return_p) {";
5192 : 284 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
5193 : 284 : s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
5194 : 284 : s.op->newline() << "#endif";
5195 : 284 : s.op->newline() << "atomic_add (kp->u.krp.nmissed, skipped_count());";
5196 : 284 : s.op->newline() << "#ifdef STP_TIMING";
5197 : 284 : s.op->newline() << "if (kp->u.krp.nmissed)";
5198 : 284 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->probe->pp, kp->u.krp.nmissed);";
5199 : 284 : s.op->newline(-1) << "#endif";
5200 : 284 : s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, skipped_count());";
5201 : 284 : s.op->newline() << "#ifdef STP_TIMING";
5202 : 284 : s.op->newline() << "if (kp->u.krp.kp.nmissed)";
5203 : 284 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->probe->pp, kp->u.krp.kp.nmissed);";
5204 : 284 : s.op->newline(-1) << "#endif";
5205 : 284 : s.op->newline(-1) << "} else {";
5206 : 284 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
5207 : 284 : s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
5208 : 284 : s.op->newline() << "#endif";
5209 : 284 : s.op->newline() << "atomic_add (kp->u.kp.nmissed, skipped_count());";
5210 : 284 : s.op->newline() << "#ifdef STP_TIMING";
5211 : 284 : s.op->newline() << "if (kp->u.kp.nmissed)";
5212 : 284 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->probe->pp, kp->u.kp.nmissed);";
5213 : 284 : s.op->newline(-1) << "#endif";
5214 : 284 : s.op->newline(-1) << "}";
5215 : 284 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
5216 : 284 : s.op->newline() << "unregister_kprobe (&kp->dummy);";
5217 : 284 : s.op->newline() << "#endif";
5218 : 284 : s.op->newline() << "sdp->registered_p = 0;";
5219 : 284 : s.op->newline(-1) << "}";
5220 : 284 : }
5221 : :
5222 : 72 : static void sdt_v3_tokenize(const string& str, vector<string>& tokens)
5223 : : {
5224 : : string::size_type pos;
5225 : 72 : string::size_type lastPos = str.find_first_not_of(" ", 0);
5226 : 72 : string::size_type nextAt = str.find("@", lastPos);
5227 : :
5228 [ - + ]: 72 : if (nextAt == string::npos)
5229 : : {
5230 : : // PR13934: Assembly probes are not forced to use the N@OP form.
5231 : : // In this case, N is inferred to be the native word size. Since we
5232 : : // don't have a nice delimiter, just split it on spaces. SDT-asm authors
5233 : : // then must not put any spaces in arguments, to avoid ambiguity.
5234 [ # # ][ # # ]: 0 : tokenize(str, tokens, " ");
[ # # ]
5235 : 72 : return;
5236 : : }
5237 : :
5238 [ + + ]: 159 : while (lastPos != string::npos)
5239 : : {
5240 : 87 : pos = nextAt + 1;
5241 : 87 : nextAt = str.find("@", pos);
5242 [ + + ]: 87 : if (nextAt == string::npos)
5243 : 72 : pos = string::npos;
5244 : : else
5245 : 15 : pos = str.rfind(" ", nextAt);
5246 : :
5247 [ + - ]: 87 : tokens.push_back(str.substr(lastPos, pos - lastPos));
5248 : 87 : lastPos = str.find_first_not_of(" ", pos);
5249 : : }
5250 : : }
5251 : :
5252 : :
5253 [ + - ][ + - ]: 72 : struct sdt_uprobe_var_expanding_visitor: public var_expanding_visitor
[ - + ]
5254 : : {
5255 : : enum regwidths {QI, QIh, HI, SI, DI};
5256 : 72 : sdt_uprobe_var_expanding_visitor(systemtap_session& s,
5257 : : int elf_machine,
5258 : : const string & process_name,
5259 : : const string & provider_name,
5260 : : const string & probe_name,
5261 : : stap_sdt_probe_type probe_type,
5262 : : const string & arg_string,
5263 : : int ac):
5264 : : session (s), elf_machine (elf_machine), process_name (process_name),
5265 : : provider_name (provider_name), probe_name (probe_name),
5266 [ + - ][ + - ]: 72 : probe_type (probe_type), arg_count ((unsigned) ac)
5267 : : {
5268 : : /* Register name mapping table depends on the elf machine of this particular
5269 : : probe target process/file, not upon the host. So we can't just
5270 : : #ifdef _i686_ etc. */
5271 : :
5272 : : #define DRI(name,num,width) dwarf_regs[name]=make_pair(num,width)
5273 [ - + ]: 72 : if (elf_machine == EM_X86_64) {
5274 [ # # ][ # # ]: 0 : DRI ("%rax", 0, DI); DRI ("%eax", 0, SI); DRI ("%ax", 0, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5275 [ # # ][ # # ]: 0 : DRI ("%al", 0, QI); DRI ("%ah", 0, QIh);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5276 [ # # ][ # # ]: 0 : DRI ("%rdx", 1, DI); DRI ("%edx", 1, SI); DRI ("%dx", 1, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5277 [ # # ][ # # ]: 0 : DRI ("%dl", 1, QI); DRI ("%dh", 1, QIh);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5278 [ # # ][ # # ]: 0 : DRI ("%rcx", 2, DI); DRI ("%ecx", 2, SI); DRI ("%cx", 2, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5279 [ # # ][ # # ]: 0 : DRI ("%cl", 2, QI); DRI ("%ch", 2, QIh);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5280 [ # # ][ # # ]: 0 : DRI ("%rbx", 3, DI); DRI ("%ebx", 3, SI); DRI ("%bx", 3, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5281 [ # # ][ # # ]: 0 : DRI ("%bl", 3, QI); DRI ("%bh", 3, QIh);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5282 [ # # ][ # # ]: 0 : DRI ("%rsi", 4, DI); DRI ("%esi", 4, SI); DRI ("%si", 4, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5283 [ # # ][ # # ]: 0 : DRI ("%sil", 4, QI);
[ # # ][ # # ]
5284 [ # # ][ # # ]: 0 : DRI ("%rdi", 5, DI); DRI ("%edi", 5, SI); DRI ("%di", 5, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5285 [ # # ][ # # ]: 0 : DRI ("%dil", 5, QI);
[ # # ][ # # ]
5286 [ # # ][ # # ]: 0 : DRI ("%rbp", 6, DI); DRI ("%ebp", 6, SI); DRI ("%bp", 6, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5287 [ # # ][ # # ]: 0 : DRI ("%bpl", 6, QI);
[ # # ][ # # ]
5288 [ # # ][ # # ]: 0 : DRI ("%rsp", 7, DI); DRI ("%esp", 7, SI); DRI ("%sp", 7, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5289 [ # # ][ # # ]: 0 : DRI ("%spl", 7, QI);
[ # # ][ # # ]
5290 [ # # ][ # # ]: 0 : DRI ("%r8", 8, DI); DRI ("%r8d", 8, SI); DRI ("%r8w", 8, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5291 [ # # ][ # # ]: 0 : DRI ("%r8b", 8, QI);
[ # # ][ # # ]
5292 [ # # ][ # # ]: 0 : DRI ("%r9", 9, DI); DRI ("%r9d", 9, SI); DRI ("%r9w", 9, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5293 [ # # ][ # # ]: 0 : DRI ("%r9b", 9, QI);
[ # # ][ # # ]
5294 [ # # ][ # # ]: 0 : DRI ("%r10", 10, DI); DRI ("%r10d", 10, SI); DRI ("%r10w", 10, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5295 [ # # ][ # # ]: 0 : DRI ("%r10b", 10, QI);
[ # # ][ # # ]
5296 [ # # ][ # # ]: 0 : DRI ("%r11", 11, DI); DRI ("%r11d", 11, SI); DRI ("%r11w", 11, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5297 [ # # ][ # # ]: 0 : DRI ("%r11b", 11, QI);
[ # # ][ # # ]
5298 [ # # ][ # # ]: 0 : DRI ("%r12", 12, DI); DRI ("%r12d", 12, SI); DRI ("%r12w", 12, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5299 [ # # ][ # # ]: 0 : DRI ("%r12b", 12, QI);
[ # # ][ # # ]
5300 [ # # ][ # # ]: 0 : DRI ("%r13", 13, DI); DRI ("%r13d", 13, SI); DRI ("%r13w", 13, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5301 [ # # ][ # # ]: 0 : DRI ("%r13b", 13, QI);
[ # # ][ # # ]
5302 [ # # ][ # # ]: 0 : DRI ("%r14", 14, DI); DRI ("%r14d", 14, SI); DRI ("%r14w", 14, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5303 [ # # ][ # # ]: 0 : DRI ("%r14b", 14, QI);
[ # # ][ # # ]
5304 [ # # ][ # # ]: 0 : DRI ("%r15", 15, DI); DRI ("%r15d", 15, SI); DRI ("%r15w", 15, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5305 [ # # ][ # # ]: 0 : DRI ("%r15b", 15, QI);
[ # # ][ # # ]
5306 [ - + ]: 72 : } else if (elf_machine == EM_386) {
5307 [ # # ][ # # ]: 0 : DRI ("%eax", 0, SI); DRI ("%ax", 0, HI); DRI ("%al", 0, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5308 [ # # ][ # # ]: 0 : DRI ("%ah", 0, QIh);
[ # # ][ # # ]
5309 [ # # ][ # # ]: 0 : DRI ("%ecx", 1, SI); DRI ("%cx", 1, HI); DRI ("%cl", 1, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5310 [ # # ][ # # ]: 0 : DRI ("%ch", 1, QIh);
[ # # ][ # # ]
5311 [ # # ][ # # ]: 0 : DRI ("%edx", 2, SI); DRI ("%dx", 2, HI); DRI ("%dl", 2, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5312 [ # # ][ # # ]: 0 : DRI ("%dh", 2, QIh);
[ # # ][ # # ]
5313 [ # # ][ # # ]: 0 : DRI ("%ebx", 3, SI); DRI ("%bx", 3, HI); DRI ("%bl", 3, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5314 [ # # ][ # # ]: 0 : DRI ("%bh", 3, QIh);
[ # # ][ # # ]
5315 [ # # ][ # # ]: 0 : DRI ("%esp", 4, SI); DRI ("%sp", 4, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5316 [ # # ][ # # ]: 0 : DRI ("%ebp", 5, SI); DRI ("%bp", 5, HI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5317 [ # # ][ # # ]: 0 : DRI ("%esi", 6, SI); DRI ("%si", 6, HI); DRI ("%sil", 6, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5318 [ # # ][ # # ]: 0 : DRI ("%edi", 7, SI); DRI ("%di", 7, HI); DRI ("%dil", 7, QI);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
5319 [ + - ][ - + ]: 72 : } else if (elf_machine == EM_PPC || elf_machine == EM_PPC64) {
5320 [ # # ][ # # ]: 0 : DRI ("%r0", 0, DI);
[ # # ][ # # ]
5321 [ # # ][ # # ]: 0 : DRI ("%r1", 1, DI);
[ # # ][ # # ]
5322 [ # # ][ # # ]: 0 : DRI ("%r2", 2, DI);
[ # # ][ # # ]
5323 [ # # ][ # # ]: 0 : DRI ("%r3", 3, DI);
[ # # ][ # # ]
5324 [ # # ][ # # ]: 0 : DRI ("%r4", 4, DI);
[ # # ][ # # ]
5325 [ # # ][ # # ]: 0 : DRI ("%r5", 5, DI);
[ # # ][ # # ]
5326 [ # # ][ # # ]: 0 : DRI ("%r6", 6, DI);
[ # # ][ # # ]
5327 [ # # ][ # # ]: 0 : DRI ("%r7", 7, DI);
[ # # ][ # # ]
5328 [ # # ][ # # ]: 0 : DRI ("%r8", 8, DI);
[ # # ][ # # ]
5329 [ # # ][ # # ]: 0 : DRI ("%r9", 9, DI);
[ # # ][ # # ]
5330 [ # # ][ # # ]: 0 : DRI ("%r10", 10, DI);
[ # # ][ # # ]
5331 [ # # ][ # # ]: 0 : DRI ("%r11", 11, DI);
[ # # ][ # # ]
5332 [ # # ][ # # ]: 0 : DRI ("%r12", 12, DI);
[ # # ][ # # ]
5333 [ # # ][ # # ]: 0 : DRI ("%r13", 13, DI);
[ # # ][ # # ]
5334 [ # # ][ # # ]: 0 : DRI ("%r14", 14, DI);
[ # # ][ # # ]
5335 [ # # ][ # # ]: 0 : DRI ("%r15", 15, DI);
[ # # ][ # # ]
5336 [ # # ][ # # ]: 0 : DRI ("%r16", 16, DI);
[ # # ][ # # ]
5337 [ # # ][ # # ]: 0 : DRI ("%r17", 17, DI);
[ # # ][ # # ]
5338 [ # # ][ # # ]: 0 : DRI ("%r18", 18, DI);
[ # # ][ # # ]
5339 [ # # ][ # # ]: 0 : DRI ("%r19", 19, DI);
[ # # ][ # # ]
5340 [ # # ][ # # ]: 0 : DRI ("%r20", 20, DI);
[ # # ][ # # ]
5341 [ # # ][ # # ]: 0 : DRI ("%r21", 21, DI);
[ # # ][ # # ]
5342 [ # # ][ # # ]: 0 : DRI ("%r22", 22, DI);
[ # # ][ # # ]
5343 [ # # ][ # # ]: 0 : DRI ("%r23", 23, DI);
[ # # ][ # # ]
5344 [ # # ][ # # ]: 0 : DRI ("%r24", 24, DI);
[ # # ][ # # ]
5345 [ # # ][ # # ]: 0 : DRI ("%r25", 25, DI);
[ # # ][ # # ]
5346 [ # # ][ # # ]: 0 : DRI ("%r26", 26, DI);
[ # # ][ # # ]
5347 [ # # ][ # # ]: 0 : DRI ("%r27", 27, DI);
[ # # ][ # # ]
5348 [ # # ][ # # ]: 0 : DRI ("%r28", 28, DI);
[ # # ][ # # ]
5349 [ # # ][ # # ]: 0 : DRI ("%r29", 29, DI);
[ # # ][ # # ]
5350 [ # # ][ # # ]: 0 : DRI ("%r30", 30, DI);
[ # # ][ # # ]
5351 [ # # ][ # # ]: 0 : DRI ("%r31", 31, DI);
[ # # ][ # # ]
5352 : : // PR11821: unadorned register "names" without -mregnames
5353 [ # # ][ # # ]: 0 : DRI ("0", 0, DI);
[ # # ][ # # ]
5354 [ # # ][ # # ]: 0 : DRI ("1", 1, DI);
[ # # ][ # # ]
5355 [ # # ][ # # ]: 0 : DRI ("2", 2, DI);
[ # # ][ # # ]
5356 [ # # ][ # # ]: 0 : DRI ("3", 3, DI);
[ # # ][ # # ]
5357 [ # # ][ # # ]: 0 : DRI ("4", 4, DI);
[ # # ][ # # ]
5358 [ # # ][ # # ]: 0 : DRI ("5", 5, DI);
[ # # ][ # # ]
5359 [ # # ][ # # ]: 0 : DRI ("6", 6, DI);
[ # # ][ # # ]
5360 [ # # ][ # # ]: 0 : DRI ("7", 7, DI);
[ # # ][ # # ]
5361 [ # # ][ # # ]: 0 : DRI ("8", 8, DI);
[ # # ][ # # ]
5362 [ # # ][ # # ]: 0 : DRI ("9", 9, DI);
[ # # ][ # # ]
5363 [ # # ][ # # ]: 0 : DRI ("10", 10, DI);
[ # # ][ # # ]
5364 [ # # ][ # # ]: 0 : DRI ("11", 11, DI);
[ # # ][ # # ]
5365 [ # # ][ # # ]: 0 : DRI ("12", 12, DI);
[ # # ][ # # ]
5366 [ # # ][ # # ]: 0 : DRI ("13", 13, DI);
[ # # ][ # # ]
5367 [ # # ][ # # ]: 0 : DRI ("14", 14, DI);
[ # # ][ # # ]
5368 [ # # ][ # # ]: 0 : DRI ("15", 15, DI);
[ # # ][ # # ]
5369 [ # # ][ # # ]: 0 : DRI ("16", 16, DI);
[ # # ][ # # ]
5370 [ # # ][ # # ]: 0 : DRI ("17", 17, DI);
[ # # ][ # # ]
5371 [ # # ][ # # ]: 0 : DRI ("18", 18, DI);
[ # # ][ # # ]
5372 [ # # ][ # # ]: 0 : DRI ("19", 19, DI);
[ # # ][ # # ]
5373 [ # # ][ # # ]: 0 : DRI ("20", 20, DI);
[ # # ][ # # ]
5374 [ # # ][ # # ]: 0 : DRI ("21", 21, DI);
[ # # ][ # # ]
5375 [ # # ][ # # ]: 0 : DRI ("22", 22, DI);
[ # # ][ # # ]
5376 [ # # ][ # # ]: 0 : DRI ("23", 23, DI);
[ # # ][ # # ]
5377 [ # # ][ # # ]: 0 : DRI ("24", 24, DI);
[ # # ][ # # ]
5378 [ # # ][ # # ]: 0 : DRI ("25", 25, DI);
[ # # ][ # # ]
5379 [ # # ][ # # ]: 0 : DRI ("26", 26, DI);
[ # # ][ # # ]
5380 [ # # ][ # # ]: 0 : DRI ("27", 27, DI);
[ # # ][ # # ]
5381 [ # # ][ # # ]: 0 : DRI ("28", 28, DI);
[ # # ][ # # ]
5382 [ # # ][ # # ]: 0 : DRI ("29", 29, DI);
[ # # ][ # # ]
5383 [ # # ][ # # ]: 0 : DRI ("30", 30, DI);
[ # # ][ # # ]
5384 [ # # ][ # # ]: 0 : DRI ("31", 31, DI);
[ # # ][ # # ]
5385 [ - + ]: 72 : } else if (elf_machine == EM_S390) {
5386 [ # # ][ # # ]: 0 : DRI ("%r0", 0, DI);
[ # # ][ # # ]
5387 [ # # ][ # # ]: 0 : DRI ("%r1", 1, DI);
[ # # ][ # # ]
5388 [ # # ][ # # ]: 0 : DRI ("%r2", 2, DI);
[ # # ][ # # ]
5389 [ # # ][ # # ]: 0 : DRI ("%r3", 3, DI);
[ # # ][ # # ]
5390 [ # # ][ # # ]: 0 : DRI ("%r4", 4, DI);
[ # # ][ # # ]
5391 [ # # ][ # # ]: 0 : DRI ("%r5", 5, DI);
[ # # ][ # # ]
5392 [ # # ][ # # ]: 0 : DRI ("%r6", 6, DI);
[ # # ][ # # ]
5393 [ # # ][ # # ]: 0 : DRI ("%r7", 7, DI);
[ # # ][ # # ]
5394 [ # # ][ # # ]: 0 : DRI ("%r8", 8, DI);
[ # # ][ # # ]
5395 [ # # ][ # # ]: 0 : DRI ("%r9", 9, DI);
[ # # ][ # # ]
5396 [ # # ][ # # ]: 0 : DRI ("%r10", 10, DI);
[ # # ][ # # ]
5397 [ # # ][ # # ]: 0 : DRI ("%r11", 11, DI);
[ # # ][ # # ]
5398 [ # # ][ # # ]: 0 : DRI ("%r12", 12, DI);
[ # # ][ # # ]
5399 [ # # ][ # # ]: 0 : DRI ("%r13", 13, DI);
[ # # ][ # # ]
5400 [ # # ][ # # ]: 0 : DRI ("%r14", 14, DI);
[ # # ][ # # ]
5401 [ # # ][ # # ]: 0 : DRI ("%r15", 15, DI);
[ # # ][ # # ]
5402 [ + - ]: 72 : } else if (elf_machine == EM_ARM) {
5403 [ + - ][ + - ]: 72 : DRI ("r0", 0, SI);
[ + - ][ + - ]
5404 [ + - ][ + - ]: 72 : DRI ("r1", 1, SI);
[ + - ][ + - ]
5405 [ + - ][ + - ]: 72 : DRI ("r2", 2, SI);
[ + - ][ + - ]
5406 [ + - ][ + - ]: 72 : DRI ("r3", 3, SI);
[ + - ][ + - ]
5407 [ + - ][ + - ]: 72 : DRI ("r4", 4, SI);
[ + - ][ + - ]
5408 [ + - ][ + - ]: 72 : DRI ("r5", 5, SI);
[ + - ][ + - ]
5409 [ + - ][ + - ]: 72 : DRI ("r6", 6, SI);
[ + - ][ + - ]
5410 [ + - ][ + - ]: 72 : DRI ("r7", 7, SI);
[ + - ][ + - ]
5411 [ + - ][ + - ]: 72 : DRI ("r8", 8, SI);
[ + - ][ + - ]
5412 [ + - ][ + - ]: 72 : DRI ("r9", 9, SI);
[ + - ][ + - ]
5413 [ + - ][ + - ]: 72 : DRI ("sl", 10, SI);
[ + - ][ + - ]
5414 [ + - ][ + - ]: 72 : DRI ("fp", 11, SI);
[ + - ][ + - ]
5415 [ + - ][ + - ]: 72 : DRI ("ip", 12, SI);
[ + - ][ + - ]
5416 [ + - ][ + - ]: 72 : DRI ("sp", 13, SI);
[ + - ][ + - ]
5417 [ + - ][ + - ]: 72 : DRI ("lr", 14, SI);
[ + - ][ + - ]
5418 [ + - ][ + - ]: 72 : DRI ("pc", 15, SI);
[ + - ][ + - ]
5419 : 0 : } else if (arg_count) {
5420 : : /* permit this case; just fall back to dwarf */
5421 : : }
5422 : : #undef DRI
5423 : :
5424 : 72 : need_debug_info = false;
5425 [ + - ]: 72 : if (probe_type == uprobe3_type)
5426 : : {
5427 [ + - ]: 72 : sdt_v3_tokenize(arg_string, arg_tokens);
5428 [ - + ]: 72 : assert(arg_count <= 12);
5429 : : }
5430 : : else
5431 : : {
5432 [ # # ][ # # ]: 0 : tokenize(arg_string, arg_tokens, " ");
[ # # ]
5433 [ # # ]: 0 : assert(arg_count <= 10);
5434 : : }
5435 : 72 : }
5436 : :
5437 : : systemtap_session& session;
5438 : : int elf_machine;
5439 : : const string & process_name;
5440 : : const string & provider_name;
5441 : : const string & probe_name;
5442 : : stap_sdt_probe_type probe_type;
5443 : : unsigned arg_count;
5444 : : vector<string> arg_tokens;
5445 : : map<string, pair<unsigned,int> > dwarf_regs;
5446 : : bool need_debug_info;
5447 : :
5448 : : void visit_target_symbol (target_symbol* e);
5449 : : void visit_target_symbol_arg (target_symbol* e);
5450 : : void visit_target_symbol_context (target_symbol* e);
5451 : : void visit_cast_op (cast_op* e);
5452 : : };
5453 : :
5454 : :
5455 : : void
5456 : 0 : sdt_uprobe_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
5457 : : {
5458 [ # # ]: 0 : if (e->addressof)
5459 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of context variable"), e->tok);
5460 : :
5461 [ # # ]: 0 : if (e->name == "$$name")
5462 : : {
5463 [ # # ]: 0 : literal_string *myname = new literal_string (probe_name);
5464 : 0 : myname->tok = e->tok;
5465 : 0 : provide(myname);
5466 : 0 : return;
5467 : : }
5468 : :
5469 [ # # ]: 0 : else if (e->name == "$$provider")
5470 : : {
5471 [ # # ]: 0 : literal_string *myname = new literal_string (provider_name);
5472 : 0 : myname->tok = e->tok;
5473 : 0 : provide(myname);
5474 : 0 : return;
5475 : : }
5476 : :
5477 [ # # ][ # # ]: 0 : else if (e->name == "$$vars" || e->name == "$$parms")
[ # # ]
5478 : : {
5479 [ # # ][ # # ]: 0 : e->assert_no_components("sdt", true);
[ # # ]
5480 : :
5481 : : // Convert $$vars to sprintf of a list of vars which we recursively evaluate
5482 : : // NB: we synthesize a new token here rather than reusing
5483 : : // e->tok, because print_format::print likes to use
5484 : : // its tok->content.
5485 [ # # ]: 0 : token* pf_tok = new token(*e->tok);
5486 : 0 : pf_tok->content = "sprintf";
5487 : :
5488 : 0 : print_format* pf = print_format::create(pf_tok);
5489 : :
5490 [ # # ]: 0 : for (unsigned i = 1; i <= arg_count; ++i)
5491 : : {
5492 [ # # ]: 0 : if (i > 1)
5493 [ # # ]: 0 : pf->raw_components += " ";
5494 [ # # ][ # # ]: 0 : target_symbol *tsym = new target_symbol;
5495 : 0 : tsym->tok = e->tok;
5496 [ # # ][ # # ]: 0 : tsym->name = "$arg" + lex_cast(i);
[ # # ][ # # ]
[ # # ]
5497 [ # # ]: 0 : pf->raw_components += tsym->name;
5498 [ # # ]: 0 : tsym->components = e->components;
5499 : :
5500 [ # # ]: 0 : expression *texp = require<expression> (tsym);
5501 [ # # ]: 0 : if (!e->components.empty() &&
[ # # # # ]
[ # # ]
5502 : 0 : e->components[0].type == target_symbol::comp_pretty_print)
5503 [ # # ]: 0 : pf->raw_components += "=%s";
5504 : : else
5505 [ # # ]: 0 : pf->raw_components += "=%#x";
5506 [ # # ]: 0 : pf->args.push_back(texp);
5507 : : }
5508 : :
5509 [ # # ]: 0 : pf->components = print_format::string_to_components(pf->raw_components);
5510 : 0 : provide (pf);
5511 : : }
5512 : : else
5513 : 0 : assert(0); // shouldn't get here
5514 : : }
5515 : :
5516 : :
5517 : : void
5518 : 72 : sdt_uprobe_var_expanding_visitor::visit_target_symbol_arg (target_symbol *e)
5519 : : {
5520 : : try
5521 : : {
5522 : 72 : unsigned argno = 0; // the N in $argN
5523 : : try
5524 : : {
5525 [ + - ][ + + ]: 72 : if (startswith(e->name, "$arg"))
5526 [ + - ][ + - ]: 48 : argno = lex_cast<unsigned>(e->name.substr(4));
[ + - ][ # # ]
5527 : : }
5528 : : catch (const runtime_error& f) // non-integral $arg suffix: e.g. $argKKKSDF
5529 : : {
5530 : : argno = 0;
5531 : : }
5532 : :
5533 [ + - ][ + + ]: 72 : if (arg_count == 0 || // a sdt.h variant without .probe-stored arg_count
[ - + ]
5534 : : argno < 1 || argno > arg_count) // a $argN with out-of-range N
5535 : : {
5536 : : // NB: Either
5537 : : // 1) uprobe1_type $argN or $FOO (we don't know the arg_count)
5538 : : // 2) uprobe2_type $FOO (no probe args)
5539 : : // both of which get resolved later.
5540 : : // Throw it now, and it might be resolved by DWARF later.
5541 : 24 : need_debug_info = true;
5542 [ + - ][ + - ]: 24 : throw semantic_error(_("target-symbol requires debuginfo"), e->tok);
5543 : : }
5544 : :
5545 [ - + ]: 48 : assert (arg_tokens.size() >= argno);
5546 [ + - ]: 48 : string asmarg = arg_tokens[argno-1]; // $arg1 => arg_tokens[0]
5547 : :
5548 : : // Now we try to parse this thing, which is an assembler operand
5549 : : // expression. If we can't, we warn, back down to need_debug_info
5550 : : // and hope for the best. Here is the syntax for a few architectures.
5551 : : // Note that the power iN syntax is only for V3 sdt.h; gcc emits the i.
5552 : : //
5553 : : // literal reg reg reg + base+index*size+offset
5554 : : // indirect offset
5555 : : // x86 $N %rR (%rR) N(%rR) O(%bR,%iR,S)
5556 : : // power iN R (R) N(R)
5557 : : // ia64 N rR [r16]
5558 : : // s390 N %rR 0(rR) N(r15)
5559 : : // arm #N rR [rR] [rR, #N]
5560 : :
5561 : 48 : expression* argexpr = 0; // filled in in case of successful parse
5562 : :
5563 [ + - ]: 48 : string percent_regnames;
5564 [ + - ]: 48 : string regnames;
5565 [ + - ]: 48 : vector<string> matches;
5566 : : long precision;
5567 : : int rc;
5568 : :
5569 : : // Parse the leading length
5570 : :
5571 [ + - ][ + - ]: 48 : if (asmarg.find('@') != string::npos)
5572 : : {
5573 [ + - ][ + - ]: 48 : precision = lex_cast<int>(asmarg.substr(0, asmarg.find('@')));
[ + - ][ + - ]
5574 [ + - ][ + - ]: 48 : asmarg = asmarg.substr(asmarg.find('@')+1);
[ + - ][ + - ]
5575 : : }
5576 : : else
5577 : : {
5578 : : // V1/V2 do not have precision field so default to signed long
5579 : : // V3 asm does not have precision field so default to unsigned long
5580 [ # # ]: 0 : if (probe_type == uprobe3_type)
5581 : 0 : precision = sizeof(long); // this is an asm probe
5582 : : else
5583 : 0 : precision = -sizeof(long);
5584 : : }
5585 : :
5586 : : // test for a numeric literal.
5587 : : // Only accept (signed) decimals throughout. XXX
5588 : :
5589 : : // PR11821. NB: on powerpc, literals are not prefixed with $,
5590 : : // so this regex does not match. But that's OK, since without
5591 : : // -mregnames, we can't tell them apart from register numbers
5592 : : // anyway. With -mregnames, we could, if gcc somehow
5593 : : // communicated to us the presence of that option, but alas it
5594 : : // doesn't. http://gcc.gnu.org/PR44995.
5595 [ + - ][ + - ]: 48 : rc = regexp_match (asmarg, "^[i\\$#][-]?[0-9][0-9]*$", matches);
[ + - ][ # # ]
5596 [ - + ]: 48 : if (! rc)
5597 : : {
5598 [ # # ]: 0 : string sn = matches[0].substr(1);
5599 : : int64_t n;
5600 : : try
5601 : : {
5602 : : // We have to pay attention to the size & sign, as gcc sometimes
5603 : : // propagates constants that don't quite match, like a negative
5604 : : // value to fill an unsigned type.
5605 [ # # # # : 0 : switch (precision)
# # # # ]
5606 : : {
5607 [ # # ]: 0 : case -1: n = lex_cast< int8_t>(sn); break;
5608 [ # # ]: 0 : case 1: n = lex_cast< uint8_t>(sn); break;
5609 [ # # ]: 0 : case -2: n = lex_cast< int16_t>(sn); break;
5610 [ # # ]: 0 : case 2: n = lex_cast<uint16_t>(sn); break;
5611 [ # # ]: 0 : case -4: n = lex_cast< int32_t>(sn); break;
5612 [ # # ]: 0 : case 4: n = lex_cast<uint32_t>(sn); break;
5613 : : default:
5614 [ # # ]: 0 : case -8: n = lex_cast< int64_t>(sn); break;
5615 [ # # ]: 0 : case 8: n = lex_cast<uint64_t>(sn); break;
5616 : : }
5617 : : }
5618 : : catch (std::runtime_error&)
5619 : : {
5620 : : goto not_matched;
5621 : : }
5622 [ # # ][ # # ]: 0 : literal_number* ln = new literal_number(n);
5623 : 0 : ln->tok = e->tok;
5624 : 0 : argexpr = ln;
5625 [ # # ][ # # ]: 0 : goto matched;
5626 : : }
5627 : :
5628 [ + - ][ - + ]: 48 : if (dwarf_regs.empty())
5629 : 0 : goto not_matched;
5630 : :
5631 : : // Build regex pieces out of the known dwarf_regs. We keep two separate
5632 : : // lists: ones with the % prefix (and thus unambigiuous even despite PR11821),
5633 : : // and ones with no prefix (and thus only usable in unambiguous contexts).
5634 [ + - ][ + - ]: 816 : for (map<string,pair<unsigned,int> >::iterator ri = dwarf_regs.begin(); ri != dwarf_regs.end(); ri++)
[ + + ]
5635 : : {
5636 [ + - ][ + - ]: 768 : string regname = ri->first;
5637 [ + - ][ - + ]: 768 : assert (regname != "");
5638 [ + - ][ + - ]: 768 : regnames += string("|")+regname;
[ + - ][ + - ]
[ + - ]
5639 [ + - ][ - + ]: 768 : if (regname[0]=='%')
5640 [ # # ][ # # ]: 0 : percent_regnames += string("|")+regname;
[ # # ][ # # ]
[ # # ]
5641 [ + - ]: 768 : }
5642 : : // clip off leading |
5643 [ + - ][ + - ]: 48 : regnames = regnames.substr(1);
[ + - ]
5644 [ + - ][ - + ]: 48 : if (percent_regnames != "")
5645 [ # # ][ # # ]: 0 : percent_regnames = percent_regnames.substr(1);
[ # # ]
5646 : :
5647 : : // test for REGISTER
5648 : : // NB: Because PR11821, we must use percent_regnames here.
5649 [ + - ][ + - ]: 48 : if (elf_machine == EM_PPC || elf_machine == EM_PPC64 || elf_machine == EM_ARM)
[ + - ]
5650 [ + - ][ + - ]: 48 : rc = regexp_match (asmarg, string("^(")+regnames+string(")$"), matches);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
5651 : : else
5652 [ # # ][ # # ]: 0 : rc = regexp_match (asmarg, string("^(")+percent_regnames+string(")$"), matches);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5653 [ + + ]: 48 : if (! rc)
5654 : : {
5655 [ + - ]: 12 : string regname = matches[1];
5656 [ + - ]: 12 : map<string,pair<unsigned,int> >::iterator ri = dwarf_regs.find (regname);
5657 [ + - ][ + - ]: 12 : if (ri != dwarf_regs.end()) // known register
5658 : : {
5659 [ + - ][ + - ]: 12 : embedded_expr *get_arg1 = new embedded_expr;
5660 [ + - ]: 12 : string width_adjust;
5661 [ + - ][ - - : 12 : switch (ri->second.second)
- + - ]
5662 : : {
5663 [ # # ]: 0 : case QI: width_adjust = ") & 0xff)"; break;
5664 [ # # ]: 0 : case QIh: width_adjust = ">>8) & 0xff)"; break;
5665 : : case HI:
5666 : : // preserve 16 bit register signness
5667 [ # # ]: 0 : width_adjust = ") & 0xffff)";
5668 [ # # ]: 0 : if (precision < 0)
5669 [ # # ]: 0 : width_adjust += " << 48 >> 48";
5670 : 0 : break;
5671 : : case SI:
5672 : : // preserve 32 bit register signness
5673 [ + - ]: 12 : width_adjust = ") & 0xffffffff)";
5674 [ - + ]: 12 : if (precision < 0)
5675 [ # # ]: 0 : width_adjust += " << 32 >> 32";
5676 : 12 : break;
5677 [ # # ]: 0 : default: width_adjust = "))";
5678 : : }
5679 [ + - ]: 12 : string type = "";
5680 [ + - ]: 12 : if (probe_type == uprobe3_type)
5681 : : type = (precision < 0
5682 [ - + ][ + - ]: 12 : ? "(int" : "(uint") + lex_cast(abs(precision) * 8) + "_t)";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
5683 [ + - ][ + - ]: 12 : type = type + "((";
[ + - ]
5684 : 12 : get_arg1->tok = e->tok;
5685 : : get_arg1->code = string("/* unprivileged */ /* pure */")
5686 : : + string(" ((int64_t)") + type
5687 [ + - ]: 12 : + (is_user_module (process_name)
5688 : : ? string("u_fetch_register(")
5689 : : : string("k_fetch_register("))
5690 [ + - ]: 12 : + lex_cast(dwarf_regs[regname].first) + string("))")
5691 [ + - ][ + - ]: 36 : + width_adjust;
[ + - ][ + - ]
[ + - ][ + - ]
[ # # ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
[ # # # # ]
5692 : 12 : argexpr = get_arg1;
5693 [ + - ][ + - ]: 12 : goto matched;
5694 [ + - ][ - + ]: 12 : }
5695 : : // invalid register name, fall through
5696 : : }
5697 : :
5698 : : int reg, offset1;
5699 : : // test for OFFSET(REGISTER) where OFFSET is +-N+-N+-N
5700 : : // NB: Despite PR11821, we can use regnames here, since the parentheses
5701 : : // make things unambiguous. (Note: gdb/stap-probe.c also parses this)
5702 : : // On ARM test for [REGISTER, OFFSET]
5703 [ + - ]: 36 : if (elf_machine == EM_ARM)
5704 : : {
5705 [ + - ][ + - ]: 36 : rc = regexp_match (asmarg, string("^\\[(")+regnames+string("), #([+-]?[0-9]+)([+-][0-9]*)?([+-][0-9]*)?\\]$"), matches);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
5706 : 36 : reg = 1;
5707 : 36 : offset1 = 2;
5708 : : }
5709 : : else
5710 : : {
5711 [ # # ][ # # ]: 0 : rc = regexp_match (asmarg, string("^([+-]?[0-9]*)([+-][0-9]*)?([+-][0-9]*)?[(](")+regnames+string(")[)]$"), matches);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5712 : 0 : reg = 4;
5713 : 0 : offset1 = 1;
5714 : : }
5715 [ + - ]: 36 : if (! rc)
5716 : : {
5717 [ + - ]: 36 : string regname;
5718 : 36 : int64_t disp = 0;
5719 [ + - ][ + - ]: 36 : if (matches[reg].length())
5720 [ + - ]: 36 : regname = matches[reg];
5721 [ + - ][ + - ]: 36 : if (dwarf_regs.find (regname) == dwarf_regs.end())
[ - + ][ # # ]
5722 : : goto not_matched;
5723 : :
5724 [ + + ]: 144 : for (int i=offset1; i <= (offset1 + 2); i++)
5725 [ + - ][ + + ]: 108 : if (matches[i].length())
5726 : : try
5727 : : {
5728 [ + - ]: 36 : disp += lex_cast<int64_t>(matches[i]); // should decode positive/negative hex/decimal
5729 : : }
5730 : : catch (const runtime_error& f) // unparseable offset
5731 : : {
5732 : : goto not_matched; // can't just 'break' out of
5733 : : // this case or use a sentinel
5734 : : // value, unfortunately
5735 : : }
5736 : :
5737 : : // synthesize user_long(%{fetch_register(R)%} + D)
5738 [ + - ][ + - ]: 36 : embedded_expr *get_arg1 = new embedded_expr;
5739 : 36 : get_arg1->tok = e->tok;
5740 : : get_arg1->code = string("/* unprivileged */ /* pure */")
5741 [ + - ]: 36 : + (is_user_module (process_name)
5742 : : ? string("u_fetch_register(")
5743 : : : string("k_fetch_register("))
5744 [ + - ][ + - ]: 72 : + lex_cast(dwarf_regs[regname].first) + string(")");
[ + - ][ # # ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ][ + - ]
[ # # # # ]
5745 : : // XXX: may we ever need to cast that to a narrower type?
5746 : :
5747 [ + - ][ + - ]: 36 : literal_number* inc = new literal_number(disp);
5748 : 36 : inc->tok = e->tok;
5749 : :
5750 [ + - ][ + - ]: 36 : binary_expression *be = new binary_expression;
5751 : 36 : be->tok = e->tok;
5752 : 36 : be->left = get_arg1;
5753 [ + - ]: 36 : be->op = "+";
5754 : 36 : be->right = inc;
5755 : :
5756 [ + - ][ + - ]: 36 : functioncall *fc = new functioncall;
5757 [ - - - + : 36 : switch (precision)
+ - - ]
5758 : : {
5759 : : case 1: case -1:
5760 [ # # ]: 0 : fc->function = "user_int8"; break;
5761 : : case 2:
5762 [ # # ]: 0 : fc->function = "user_uint16"; break;
5763 : : case -2:
5764 [ # # ]: 0 : fc->function = "user_int16"; break;
5765 : : case 4:
5766 [ + - ]: 32 : fc->function = "user_uint32"; break;
5767 : : case -4:
5768 [ + - ]: 4 : fc->function = "user_int32"; break;
5769 : : case 8: case -8:
5770 [ # # ]: 0 : fc->function = "user_int64"; break;
5771 [ # # ]: 0 : default: fc->function = "user_long";
5772 : : }
5773 : 36 : fc->tok = e->tok;
5774 [ + - ]: 36 : fc->args.push_back(be);
5775 : :
5776 : 36 : argexpr = fc;
5777 [ + - ][ - + ]: 36 : goto matched;
5778 : : }
5779 : :
5780 : : // test for OFFSET(BASE_REGISTER,INDEX_REGISTER[,SCALE]) where OFFSET is +-N+-N+-N
5781 : : // NB: Despite PR11821, we can use regnames here, since the parentheses
5782 : : // make things unambiguous. (Note: gdb/stap-probe.c also parses this)
5783 [ # # ][ # # ]: 0 : rc = regexp_match (asmarg, string("^([+-]?[0-9]*)([+-][0-9]*)?([+-][0-9]*)?[(](")+regnames+string("),(")+regnames+string(")(,[1248])?[)]$"), matches);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5784 [ # # ]: 0 : if (! rc)
5785 : : {
5786 [ # # ]: 0 : string baseregname;
5787 [ # # ]: 0 : string indexregname;
5788 : 0 : int64_t disp = 0;
5789 : 0 : short scale = 1;
5790 : :
5791 [ # # ][ # # ]: 0 : if (matches[6].length())
5792 : : try
5793 : : {
5794 [ # # ][ # # ]: 0 : scale = lex_cast<short>(matches[6].substr(1)); // NB: skip the comma!
[ # # ][ # # ]
5795 : : // We could verify that scale is one of 1,2,4,8,
5796 : : // but it doesn't really matter. An erroneous
5797 : : // address merely results in run-time errors.
5798 : : }
5799 : : catch (const runtime_error &f) // unparseable scale
5800 : : {
5801 : : goto not_matched;
5802 : : }
5803 : :
5804 [ # # ][ # # ]: 0 : if (matches[4].length())
5805 [ # # ]: 0 : baseregname = matches[4];
5806 [ # # ][ # # ]: 0 : if (dwarf_regs.find (baseregname) == dwarf_regs.end())
[ # # ]
5807 : : goto not_matched;
5808 : :
5809 [ # # ][ # # ]: 0 : if (matches[5].length())
5810 [ # # ]: 0 : indexregname = matches[5];
5811 [ # # ][ # # ]: 0 : if (dwarf_regs.find (indexregname) == dwarf_regs.end())
[ # # ][ # # ]
5812 : : goto not_matched;
5813 : :
5814 [ # # ]: 0 : for (int i = 1; i <= 3; i++) // up to three OFFSET terms
5815 [ # # ][ # # ]: 0 : if (matches[i].length())
5816 : : try
5817 : : {
5818 [ # # ]: 0 : disp += lex_cast<int64_t>(matches[i]); // should decode positive/negative hex/decimal
5819 : : }
5820 : : catch (const runtime_error& f) // unparseable offset
5821 : : {
5822 : : goto not_matched; // can't just 'break' out of
5823 : : // this case or use a sentinel
5824 : : // value, unfortunately
5825 : : }
5826 : :
5827 : : // synthesize user_long(%{fetch_register(R1)+fetch_register(R2)*N%} + D)
5828 : :
5829 [ # # ][ # # ]: 0 : embedded_expr *get_arg1 = new embedded_expr;
5830 [ # # ]: 0 : string regfn = is_user_module (process_name)
5831 : : ? string("u_fetch_register")
5832 [ # # ][ # # ]: 0 : : string("k_fetch_register"); // NB: in practice sdt.h probes are for userspace only
[ # # ][ # # ]
[ # # ]
[ # # # # ]
5833 : :
5834 : 0 : get_arg1->tok = e->tok;
5835 : : get_arg1->code = string("/* unprivileged */ /* pure */")
5836 [ # # ]: 0 : + regfn + string("(")+lex_cast(dwarf_regs[baseregname].first)+string(")")
5837 : : + string("+(")
5838 [ # # ]: 0 : + regfn + string("(")+lex_cast(dwarf_regs[indexregname].first)+string(")")
5839 : : + string("*")
5840 : : + lex_cast(scale)
5841 [ # # ][ # # ]: 0 : + string(")");
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5842 : :
5843 : : // NB: could plop this +DISPLACEMENT bit into the embedded-c expression too
5844 [ # # ][ # # ]: 0 : literal_number* inc = new literal_number(disp);
5845 : 0 : inc->tok = e->tok;
5846 : :
5847 [ # # ][ # # ]: 0 : binary_expression *be = new binary_expression;
5848 : 0 : be->tok = e->tok;
5849 : 0 : be->left = get_arg1;
5850 [ # # ]: 0 : be->op = "+";
5851 : 0 : be->right = inc;
5852 : :
5853 [ # # ][ # # ]: 0 : functioncall *fc = new functioncall;
5854 [ # # # # : 0 : switch (precision)
# # # ]
5855 : : {
5856 : : case 1: case -1:
5857 [ # # ]: 0 : fc->function = "user_int8"; break;
5858 : : case 2:
5859 [ # # ]: 0 : fc->function = "user_uint16"; break;
5860 : : case -2:
5861 [ # # ]: 0 : fc->function = "user_int16"; break;
5862 : : case 4:
5863 [ # # ]: 0 : fc->function = "user_uint32"; break;
5864 : : case -4:
5865 [ # # ]: 0 : fc->function = "user_int32"; break;
5866 : : case 8: case -8:
5867 [ # # ]: 0 : fc->function = "user_int64"; break;
5868 [ # # ]: 0 : default: fc->function = "user_long";
5869 : : }
5870 : 0 : fc->tok = e->tok;
5871 [ # # ]: 0 : fc->args.push_back(be);
5872 : :
5873 : 0 : argexpr = fc;
5874 [ # # ][ # # ]: 0 : goto matched;
[ # # ][ # # ]
[ # # ]
5875 : : }
5876 : :
5877 : :
5878 : : not_matched:
5879 : : // The asmarg operand was not recognized. Back down to dwarf.
5880 [ # # ]: 0 : if (! session.suppress_warnings)
5881 : : {
5882 [ # # ]: 0 : if (probe_type == UPROBE3_TYPE)
5883 [ # # ][ # # ]: 0 : session.print_warning (_F("Can't parse SDT_V3 operand '%s'", asmarg.c_str()), e->tok);
[ # # ][ # # ]
5884 : : else // must be *PROBE2; others don't get asm operands
5885 : 0 : session.print_warning (_F("Downgrading SDT_V2 probe argument to dwarf, can't parse '%s'",
5886 [ # # ][ # # ]: 0 : asmarg.c_str()), e->tok);
[ # # ][ # # ]
5887 : : }
5888 [ # # ]: 0 : assert (argexpr == 0);
5889 : 0 : need_debug_info = true;
5890 [ # # ][ # # ]: 0 : throw semantic_error(_("SDT asm not understood, requires debuginfo"), e->tok);
5891 : :
5892 : : matched:
5893 [ - + ]: 48 : assert (argexpr != 0);
5894 : :
5895 [ - + ]: 48 : if (session.verbose > 2)
5896 : : //TRANSLATORS: We're mapping the operand to a new expression*.
5897 [ # # ][ # # ]: 0 : clog << _F("mapped asm operand %s to ", asmarg.c_str()) << *argexpr << endl;
[ # # ][ # # ]
[ # # ][ # # ]
5898 : :
5899 [ + - ][ + - ]: 48 : if (e->components.empty()) // We have a scalar
5900 : : {
5901 [ - + ]: 48 : if (e->addressof)
5902 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of sdt variable"), e->tok);
5903 [ + - ]: 48 : provide (argexpr);
5904 : : return;
5905 : : }
5906 : : else // $var->foo
5907 : : {
5908 [ # # ][ # # ]: 0 : cast_op *cast = new cast_op;
5909 [ # # ]: 0 : cast->name = "@cast";
5910 : 0 : cast->tok = e->tok;
5911 : 0 : cast->operand = argexpr;
5912 [ # # ]: 0 : cast->components = e->components;
5913 [ # # ][ # # ]: 0 : cast->type_name = probe_name + "_arg" + lex_cast(argno);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
5914 [ # # ]: 0 : cast->module = process_name;
5915 [ # # ]: 0 : cast->visit(this);
5916 : : return;
5917 [ + - ][ + - ]: 96 : }
[ + - ][ + - ]
5918 : :
5919 : : /* NOTREACHED */
5920 : : }
5921 [ - + ]: 48 : catch (const semantic_error &er)
5922 : : {
5923 [ - + ]: 24 : e->chain (er);
5924 [ - + ]: 24 : provide (e);
5925 : : }
5926 : : }
5927 : :
5928 : :
5929 : : void
5930 : 72 : sdt_uprobe_var_expanding_visitor::visit_target_symbol (target_symbol* e)
5931 : : {
5932 : : try
5933 : : {
5934 [ + - ][ + - ]: 216 : assert(e->name.size() > 0
[ + - ][ # # ]
[ # # ]
5935 : : && ((e->name[0] == '$' && e->target_name == "")
5936 [ + - ][ + - ]: 216 : || (e->name == "@var" && e->target_name != "")));
[ - + ][ # # ]
[ # # ]
5937 : :
5938 [ + - ][ + - ]: 72 : if (e->name == "$$name" || e->name == "$$provider" || e->name == "$$parms" || e->name == "$$vars")
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
5939 [ # # ]: 0 : visit_target_symbol_context (e);
5940 : : else
5941 [ + - ]: 72 : visit_target_symbol_arg (e);
5942 : : }
5943 [ # # ]: : catch (const semantic_error &er)
5944 : : {
5945 [ # # ]: : e->chain (er);
5946 [ # # ]: : provide (e);
5947 : : }
5948 : 72 : }
5949 : :
5950 : :
5951 : : void
5952 : 0 : sdt_uprobe_var_expanding_visitor::visit_cast_op (cast_op* e)
5953 : : {
5954 : : // Fill in our current module context if needed
5955 [ # # ]: 0 : if (e->module.empty())
5956 : 0 : e->module = process_name;
5957 : :
5958 : 0 : var_expanding_visitor::visit_cast_op(e);
5959 : 0 : }
5960 : :
5961 : :
5962 : : void
5963 : 0 : plt_expanding_visitor::visit_target_symbol (target_symbol *e)
5964 : : {
5965 : : try
5966 : : {
5967 [ # # ][ # # ]: 0 : if (e->name == "$$name")
5968 : : {
5969 [ # # ][ # # ]: 0 : literal_string *myname = new literal_string (entry);
5970 : 0 : myname->tok = e->tok;
5971 [ # # ]: 0 : provide(myname);
5972 : 0 : return;
5973 : : }
5974 : :
5975 : : // variable not found -> throw a semantic error
5976 : : // (only to be caught right away, but this may be more complex later...)
5977 [ # # ]: 0 : string alternatives = "$$name";
5978 : 0 : throw semantic_error(_F("unable to find plt variable '%s' (alternatives: %s)",
5979 [ # # ][ # # ]: 0 : e->name.c_str(), alternatives.c_str()), e->tok);
[ # # ][ # # ]
5980 : : }
5981 [ # # ]: : catch (const semantic_error &er)
5982 : : {
5983 [ # # ]: : e->chain (er);
5984 [ # # ]: : provide (e);
5985 : : }
5986 : : }
5987 : :
5988 : :
5989 [ + - ][ + - ]: 16 : struct sdt_query : public base_query
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
5990 : : {
5991 : : sdt_query(probe * base_probe, probe_point * base_loc,
5992 : : dwflpp & dw, literal_map_t const & params,
5993 : : vector<derived_probe *> & results, const string user_lib);
5994 : :
5995 : : void query_library (const char *data);
5996 : 0 : void query_plt (const char *entry, size_t addr) {}
5997 : : void handle_query_module();
5998 : :
5999 : : private:
6000 : : stap_sdt_probe_type probe_type;
6001 : : enum { probe_section=0, note_section=1, unknown_section=-1 } probe_loc;
6002 : : probe * base_probe;
6003 : : probe_point * base_loc;
6004 : : literal_map_t const & params;
6005 : : vector<derived_probe *> & results;
6006 : : string pp_mark;
6007 : : string pp_provider;
6008 : : string user_lib;
6009 : :
6010 : : set<string> probes_handled;
6011 : :
6012 : : Elf_Data *pdata;
6013 : : size_t probe_scn_offset;
6014 : : size_t probe_scn_addr;
6015 : : uint64_t arg_count;
6016 : : GElf_Addr base;
6017 : : GElf_Addr pc;
6018 : : string arg_string;
6019 : : string probe_name;
6020 : : string provider_name;
6021 : : GElf_Addr semaphore_load_offset;
6022 : : Dwarf_Addr semaphore;
6023 : :
6024 : : bool init_probe_scn();
6025 : : bool get_next_probe();
6026 : : void iterate_over_probe_entries();
6027 : : void handle_probe_entry();
6028 : :
6029 : : static void setup_note_probe_entry_callback (void *object, int type, const char *data, size_t len);
6030 : : void setup_note_probe_entry (int type, const char *data, size_t len);
6031 : :
6032 : : void convert_probe(probe *base);
6033 : : void record_semaphore(vector<derived_probe *> & results, unsigned start);
6034 : : probe* convert_location();
6035 [ + - ][ + - ]: 72 : bool have_uprobe() {return probe_type == uprobe1_type || probe_type == uprobe2_type || probe_type == uprobe3_type;}
[ + - ]
6036 : 72 : bool have_debuginfo_uprobe(bool need_debug_info)
6037 : : {return probe_type == uprobe1_type
6038 : : || ((probe_type == uprobe2_type || probe_type == uprobe3_type)
6039 [ + - ][ + - ]: 72 : && need_debug_info);}
[ + - ][ + + ]
6040 [ + - ][ + - ]: 72 : bool have_debuginfoless_uprobe() {return probe_type == uprobe2_type || probe_type == uprobe3_type;}
6041 : : };
6042 : :
6043 : :
6044 : 16 : sdt_query::sdt_query(probe * base_probe, probe_point * base_loc,
6045 : : dwflpp & dw, literal_map_t const & params,
6046 : : vector<derived_probe *> & results, const string user_lib):
6047 : : base_query(dw, params), probe_type(unknown_probe_type),
6048 : : probe_loc(unknown_section), base_probe(base_probe),
6049 : : base_loc(base_loc), params(params), results(results), user_lib(user_lib),
6050 : : probe_scn_offset(0), probe_scn_addr(0), arg_count(0), base(0), pc(0),
6051 [ + - ][ + - ]: 16 : semaphore_load_offset(0), semaphore(0)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
6052 : : {
6053 [ + - ][ - + ]: 16 : assert(get_string_param(params, TOK_MARK, pp_mark));
6054 [ + - ]: 16 : get_string_param(params, TOK_PROVIDER, pp_provider); // pp_provider == "" -> unspecified
6055 : :
6056 : : // PR10245: permit usage of dtrace-y "-" separator in marker name;
6057 : : // map it to double-underscores.
6058 : 16 : size_t pos = 0;
6059 : 6 : while (1) // there may be more than one
6060 : : {
6061 [ + - ]: 22 : size_t i = pp_mark.find("-", pos);
6062 [ + + ]: 22 : if (i == string::npos) break;
6063 [ + - ]: 6 : pp_mark.replace (i, 1, "__");
6064 : 6 : pos = i+1; // resume searching after the inserted __
6065 : : }
6066 : :
6067 : : // XXX: same for pp_provider?
6068 : 16 : }
6069 : :
6070 : :
6071 : : void
6072 : 72 : sdt_query::handle_probe_entry()
6073 : : {
6074 [ - + ][ # # ]: 144 : if (! have_uprobe()
[ + - ]
6075 [ # # ][ - + ]: 72 : && !probes_handled.insert(probe_name).second)
[ # # ]
6076 : 72 : return;
6077 : :
6078 [ - + ]: 72 : if (sess.verbose > 3)
6079 : : {
6080 : : //TRANSLATORS: Describing what probe type (kprobe or uprobe) the probe
6081 : : //TRANSLATORS: is matched to.
6082 [ # # ][ # # ]: 0 : clog << _F("matched probe_name %s probe type ", probe_name.c_str());
[ # # ][ # # ]
6083 [ # # # # ]: 0 : switch (probe_type)
6084 : : {
6085 : : case uprobe1_type:
6086 [ # # ][ # # ]: 0 : clog << "uprobe1 at 0x" << hex << pc << dec << endl;
[ # # ][ # # ]
[ # # ]
6087 : 0 : break;
6088 : : case uprobe2_type:
6089 [ # # ][ # # ]: 0 : clog << "uprobe2 at 0x" << hex << pc << dec << endl;
[ # # ][ # # ]
[ # # ]
6090 : 0 : break;
6091 : : case uprobe3_type:
6092 [ # # ][ # # ]: 0 : clog << "uprobe3 at 0x" << hex << pc << dec << endl;
[ # # ][ # # ]
[ # # ]
6093 : 0 : break;
6094 : : default:
6095 [ # # ][ # # ]: 0 : clog << "unknown!" << endl;
6096 : 0 : break;
6097 : : }
6098 : : }
6099 : :
6100 : : // Extend the derivation chain
6101 [ + - ]: 72 : probe *new_base = convert_location();
6102 : 72 : probe_point *new_location = new_base->locations[0];
6103 : :
6104 : 72 : bool need_debug_info = false;
6105 : :
6106 : : // We could get the Elf* from either dwarf_getelf(dwfl_module_getdwarf(...))
6107 : : // or dwfl_module_getelf(...). We only need it for the machine type, which
6108 : : // should be the same. The bias is used for relocating debuginfoless probes,
6109 : : // though, so that must come from the possibly-prelinked ELF file, not DWARF.
6110 : : Dwarf_Addr bias;
6111 [ + - ]: 72 : Elf* elf = dwfl_module_getelf (dw.mod_info->mod, &bias);
6112 : :
6113 : : /* Figure out the architecture of this particular ELF file. The
6114 : : dwarfless register-name mappings depend on it. */
6115 : : GElf_Ehdr ehdr_mem;
6116 [ + - ]: 72 : GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
6117 [ - + ][ # # ]: 72 : if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
[ # # ][ # # ]
[ # # ]
6118 [ - + ]: 72 : assert(em);
6119 : 72 : int elf_machine = em->e_machine;
6120 : : sdt_uprobe_var_expanding_visitor svv (sess, elf_machine, module_val,
6121 : : provider_name, probe_name,
6122 [ + - ]: 72 : probe_type, arg_string, arg_count);
6123 [ + - ]: 72 : svv.replace (new_base->body);
6124 : 72 : need_debug_info = svv.need_debug_info;
6125 : :
6126 : : // XXX: why not derive_probes() in the uprobes case too?
6127 [ + - ]: 72 : literal_map_t params;
6128 [ + + ]: 216 : for (unsigned i = 0; i < new_location->components.size(); ++i)
6129 : : {
6130 : 144 : probe_point::component *c = new_location->components[i];
6131 [ + - ]: 144 : params[c->functor] = c->arg;
6132 : : }
6133 : :
6134 : 72 : unsigned prior_results_size = results.size();
6135 [ + - ][ + - ]: 72 : dwarf_query q(new_base, new_location, dw, params, results, "", "");
[ + - ][ + - ]
[ + - ]
6136 : 72 : q.has_mark = true; // enables mid-statement probing
6137 : :
6138 : : // V1 probes always need dwarf info
6139 : : // V2+ probes need dwarf info in case of a variable reference
6140 [ + + ]: 72 : if (have_debuginfo_uprobe(need_debug_info))
6141 [ + - ]: 24 : dw.iterate_over_modules(&query_module, &q);
6142 : :
6143 : : // For V2+ probes, if variable references weren't used or failed (PR14369),
6144 : : // then try with the more direct approach. Unresolved $vars might still
6145 : : // cause their own error, but this gives them a chance to be optimized out.
6146 [ + - ][ + + ]: 72 : if (have_debuginfoless_uprobe() && results.size() == prior_results_size)
[ + + ]
6147 : : {
6148 [ + - ]: 48 : string section;
6149 : 48 : Dwarf_Addr reloc_addr = q.statement_num_val + bias;
6150 [ + - ][ - + ]: 48 : if (dwfl_module_relocations (q.dw.mod_info->mod) > 0)
6151 : : {
6152 [ # # ]: 0 : dwfl_module_relocate_address (q.dw.mod_info->mod, &reloc_addr);
6153 [ # # ]: 0 : section = ".dynamic";
6154 : : }
6155 : : else
6156 [ + - ]: 48 : section = ".absolute";
6157 : :
6158 : : uprobe_derived_probe* p =
6159 : : new uprobe_derived_probe ("", "", 0,
6160 : : path_remove_sysroot(sess,q.module_val),
6161 : : section,
6162 [ + - ][ + - ]: 48 : q.statement_num_val, reloc_addr, q, 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
6163 [ + - ]: 48 : p->saveargs (arg_count);
6164 [ + - ][ + - ]: 48 : results.push_back (p);
6165 : : }
6166 [ + - ]: 72 : sess.unwindsym_modules.insert (dw.module_name);
6167 [ + - ][ + - ]: 72 : record_semaphore(results, prior_results_size);
[ + - ][ + - ]
6168 : : }
6169 : :
6170 : :
6171 : : void
6172 : 10 : sdt_query::handle_query_module()
6173 : : {
6174 [ + + ]: 10 : if (!init_probe_scn())
6175 : 10 : return;
6176 : :
6177 [ - + ]: 3 : if (sess.verbose > 3)
6178 : 0 : clog << "TOK_MARK: " << pp_mark << " TOK_PROVIDER: " << pp_provider << endl;
6179 : :
6180 [ + - ]: 3 : if (probe_loc == note_section)
6181 : : {
6182 : : GElf_Shdr shdr_mem;
6183 [ + - ][ + - ]: 3 : GElf_Shdr *shdr = dw.get_section (".stapsdt.base", &shdr_mem);
[ + - ]
6184 : :
6185 : : // The 'base' lets us adjust the hardcoded addresses in notes for prelink
6186 : : // effects. The 'semaphore_load_offset' accounts for the difference in
6187 : : // load addresses between text and data, so the semaphore can be
6188 : : // converted to a file offset if needed.
6189 [ + - ]: 3 : if (shdr)
6190 : : {
6191 : 3 : base = shdr->sh_addr;
6192 : 3 : GElf_Addr base_offset = shdr->sh_offset;
6193 [ + - ][ + - ]: 3 : shdr = dw.get_section (".probes", &shdr_mem);
[ + - ]
6194 [ - + ]: 3 : if (shdr)
6195 : : semaphore_load_offset =
6196 : 0 : (shdr->sh_addr - shdr->sh_offset) - (base - base_offset);
6197 : : }
6198 : : else
6199 : 0 : base = semaphore_load_offset = 0;
6200 : :
6201 [ + - ]: 3 : dw.iterate_over_notes ((void*) this, &sdt_query::setup_note_probe_entry_callback);
6202 : : }
6203 [ # # ]: 0 : else if (probe_loc == probe_section)
6204 : 0 : iterate_over_probe_entries ();
6205 : : }
6206 : :
6207 : :
6208 : : bool
6209 : 10 : sdt_query::init_probe_scn()
6210 : : {
6211 : : Elf* elf;
6212 : : GElf_Shdr shdr_mem;
6213 : :
6214 [ + - ][ + - ]: 10 : GElf_Shdr *shdr = dw.get_section (".note.stapsdt", &shdr_mem);
[ + - ]
6215 [ + + ]: 10 : if (shdr)
6216 : : {
6217 : 3 : probe_loc = note_section;
6218 : 3 : return true;
6219 : : }
6220 : :
6221 [ + - ][ + - ]: 7 : shdr = dw.get_section (".probes", &shdr_mem, &elf);
[ + - ]
6222 [ - + ]: 7 : if (shdr)
6223 : : {
6224 [ # # ]: 0 : pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE);
6225 : 0 : probe_scn_offset = 0;
6226 : 0 : probe_scn_addr = shdr->sh_addr;
6227 [ # # ]: 0 : assert (pdata != NULL);
6228 [ # # ]: 0 : if (sess.verbose > 4)
6229 [ # # ][ # # ]: 0 : clog << "got .probes elf scn_addr@0x" << probe_scn_addr << ", size: "
[ # # ]
6230 [ # # ][ # # ]: 0 : << pdata->d_size << endl;
6231 : 0 : probe_loc = probe_section;
6232 : 0 : return true;
6233 : : }
6234 : : else
6235 : 10 : return false;
6236 : : }
6237 : :
6238 : : void
6239 : 72 : sdt_query::setup_note_probe_entry_callback (void *object, int type, const char *data, size_t len)
6240 : : {
6241 : 72 : sdt_query *me = (sdt_query*)object;
6242 : 72 : me->setup_note_probe_entry (type, data, len);
6243 : 72 : }
6244 : :
6245 : :
6246 : : void
6247 : 72 : sdt_query::setup_note_probe_entry (int type, const char *data, size_t len)
6248 : : {
6249 : : // if (nhdr.n_namesz == sizeof _SDT_NOTE_NAME
6250 : : // && !memcmp (data->d_buf + name_off,
6251 : : // _SDT_NOTE_NAME, sizeof _SDT_NOTE_NAME))
6252 : :
6253 : : // probes are in the .note.stapsdt section
6254 : : #define _SDT_NOTE_TYPE 3
6255 [ + - ]: 72 : if (type != _SDT_NOTE_TYPE)
6256 : : return;
6257 : :
6258 : : union
6259 : : {
6260 : : Elf64_Addr a64[3];
6261 : : Elf32_Addr a32[3];
6262 : : } buf;
6263 : : Dwarf_Addr bias;
6264 [ + - ]: 72 : Elf* elf = (dwfl_module_getelf (dw.mod_info->mod, &bias));
6265 : : Elf_Data dst =
6266 : : {
6267 : : &buf, ELF_T_ADDR, EV_CURRENT,
6268 [ + - ]: 72 : gelf_fsize (elf, ELF_T_ADDR, 3, EV_CURRENT), 0, 0
6269 : 144 : };
6270 [ - + ]: 72 : assert (dst.d_size <= sizeof buf);
6271 : :
6272 [ + - ]: 72 : if (len < dst.d_size + 3)
6273 : : return;
6274 : :
6275 : : Elf_Data src =
6276 : : {
6277 : : (void *) data, ELF_T_ADDR, EV_CURRENT,
6278 : : dst.d_size, 0, 0
6279 : 72 : };
6280 : :
6281 [ - + ]: 72 : if (gelf_xlatetom (elf, &dst, &src,
6282 [ + - ][ + - ]: 72 : elf_getident (elf, NULL)[EI_DATA]) == NULL)
6283 [ # # ][ # # ]: 0 : printf ("gelf_xlatetom: %s", elf_errmsg (-1));
6284 : :
6285 : 72 : probe_type = uprobe3_type;
6286 : 72 : const char * provider = data + dst.d_size;
6287 : :
6288 : 72 : const char *name = (const char*)memchr (provider, '\0', data + len - provider);
6289 [ + - ]: 72 : if(name++ == NULL)
6290 : : return;
6291 : :
6292 : 72 : const char *args = (const char*)memchr (name, '\0', data + len - name);
6293 [ + - ][ - + ]: 72 : if (args++ == NULL || memchr (args, '\0', data + len - name) != data + len - 1)
[ + - ]
6294 : : return;
6295 : :
6296 [ + - ]: 72 : provider_name = provider;
6297 [ + - ]: 72 : probe_name = name;
6298 [ + - ]: 72 : arg_string = args;
6299 : :
6300 : : // Did we find a matching probe?
6301 [ + - ][ + - ]: 144 : if (! (dw.function_name_matches_pattern (probe_name, pp_mark)
6302 [ + - ]: 72 : && ((pp_provider == "")
6303 [ + - ][ - + ]: 144 : || dw.function_name_matches_pattern (provider_name, pp_provider))))
[ # # ][ # # ]
6304 : : return;
6305 : :
6306 : : // PR13934: Assembly probes are not forced to use the N@OP form.
6307 : : // If we have '@' then great, else count based on space-delimiters.
6308 [ + - ][ + - ]: 72 : arg_count = count(arg_string.begin(), arg_string.end(), '@');
[ + - ]
6309 [ - + ][ # # ]: 72 : if (!arg_count && !arg_string.empty())
[ # # ][ - + ]
6310 [ # # ][ # # ]: 0 : arg_count = 1 + count(arg_string.begin(), arg_string.end(), ' ');
[ # # ]
6311 : :
6312 : : GElf_Addr base_ref;
6313 [ + - ][ + - ]: 72 : if (gelf_getclass (elf) == ELFCLASS32)
6314 : : {
6315 : 72 : pc = buf.a32[0];
6316 : 72 : base_ref = buf.a32[1];
6317 : 72 : semaphore = buf.a32[2];
6318 : : }
6319 : : else
6320 : : {
6321 : 0 : pc = buf.a64[0];
6322 : 0 : base_ref = buf.a64[1];
6323 : 0 : semaphore = buf.a64[2];
6324 : : }
6325 : :
6326 : 72 : semaphore += base - base_ref;
6327 : 72 : pc += base - base_ref;
6328 : :
6329 : : // The semaphore also needs the ELF bias added now, so
6330 : : // record_semaphore can properly relocate it later.
6331 : 72 : semaphore += bias;
6332 : :
6333 [ - + ]: 72 : if (sess.verbose > 4)
6334 [ # # ][ # # ]: 0 : clog << _F(" saw .note.stapsdt %s%s ", probe_name.c_str(), (provider_name != "" ? _(" (provider ")+provider_name+") " : "").c_str()) << "@0x" << hex << pc << dec << endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
6335 : :
6336 [ + - ]: 72 : handle_probe_entry();
6337 : : }
6338 : :
6339 : :
6340 : : void
6341 : 0 : sdt_query::iterate_over_probe_entries()
6342 : : {
6343 : : // probes are in the .probe section
6344 [ # # ]: 0 : while (probe_scn_offset < pdata->d_size)
6345 : : {
6346 : 0 : stap_sdt_probe_entry_v1 *pbe_v1 = (stap_sdt_probe_entry_v1 *) ((char*)pdata->d_buf + probe_scn_offset);
6347 : 0 : stap_sdt_probe_entry_v2 *pbe_v2 = (stap_sdt_probe_entry_v2 *) ((char*)pdata->d_buf + probe_scn_offset);
6348 : 0 : probe_type = (stap_sdt_probe_type)(pbe_v1->type_a);
6349 [ # # ]: 0 : if (! have_uprobe())
6350 : : {
6351 : : // Unless this is a mangled .probes section, this happens
6352 : : // because the name of the probe comes first, followed by
6353 : : // the sentinel.
6354 [ # # ]: 0 : if (sess.verbose > 5)
6355 [ # # ][ # # ]: 0 : clog << _F("got unknown probe_type : 0x%x", probe_type) << endl;
6356 : 0 : probe_scn_offset += sizeof(__uint32_t);
6357 : 0 : continue;
6358 : : }
6359 [ # # ]: 0 : if ((long)pbe_v1 % sizeof(__uint64_t)) // we have stap_sdt_probe_entry_v1.type_b
6360 : : {
6361 : 0 : pbe_v1 = (stap_sdt_probe_entry_v1*)((char*)pbe_v1 - sizeof(__uint32_t));
6362 [ # # ]: 0 : if (pbe_v1->type_b != uprobe1_type)
6363 : 0 : continue;
6364 : : }
6365 : :
6366 [ # # ]: 0 : if (probe_type == uprobe1_type)
6367 : : {
6368 [ # # ]: 0 : if (pbe_v1->name == 0) // No name possibly means we have a .so with a relocation
6369 : 0 : return;
6370 : 0 : semaphore = 0;
6371 : 0 : probe_name = (char*)((char*)pdata->d_buf + pbe_v1->name - (char*)probe_scn_addr);
6372 : 0 : provider_name = ""; // unknown
6373 : 0 : pc = pbe_v1->arg;
6374 : 0 : arg_count = 0;
6375 : 0 : probe_scn_offset += sizeof (stap_sdt_probe_entry_v1);
6376 : : }
6377 [ # # ]: 0 : else if (probe_type == uprobe2_type)
6378 : : {
6379 [ # # ]: 0 : if (pbe_v2->name == 0) // No name possibly means we have a .so with a relocation
6380 : 0 : return;
6381 : 0 : semaphore = pbe_v2->semaphore;
6382 : 0 : probe_name = (char*)((char*)pdata->d_buf + pbe_v2->name - (char*)probe_scn_addr);
6383 : 0 : provider_name = (char*)((char*)pdata->d_buf + pbe_v2->provider - (char*)probe_scn_addr);
6384 : 0 : arg_count = pbe_v2->arg_count;
6385 : 0 : pc = pbe_v2->pc;
6386 [ # # ]: 0 : if (pbe_v2->arg_string)
6387 : 0 : arg_string = (char*)((char*)pdata->d_buf + pbe_v2->arg_string - (char*)probe_scn_addr);
6388 : : // skip over pbe_v2, probe_name text and provider text
6389 : 0 : probe_scn_offset = ((long)(pbe_v2->name) - (long)(probe_scn_addr)) + probe_name.length();
6390 : 0 : probe_scn_offset += sizeof (__uint32_t) - probe_scn_offset % sizeof (__uint32_t);
6391 : : }
6392 [ # # ]: 0 : if (sess.verbose > 4)
6393 [ # # ][ # # ]: 0 : clog << _("saw .probes ") << probe_name << (provider_name != "" ? _(" (provider ")+provider_name+") " : "")
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
6394 [ # # ][ # # ]: 0 : << "@0x" << hex << pc << dec << endl;
[ # # ][ # # ]
[ # # ]
6395 : :
6396 [ # # # # : 0 : if (dw.function_name_matches_pattern (probe_name, pp_mark)
# # ][ # # ]
6397 : 0 : && ((pp_provider == "") || dw.function_name_matches_pattern (provider_name, pp_provider)))
6398 : 0 : handle_probe_entry ();
6399 : : }
6400 : : }
6401 : :
6402 : :
6403 : : void
6404 : 72 : sdt_query::record_semaphore (vector<derived_probe *> & results, unsigned start)
6405 : : {
6406 [ + + ]: 216 : for (unsigned i=0; i<2; i++) {
6407 : : // prefer with-provider symbol; look without provider prefix for backward compatibility only
6408 [ + + ][ + - ]: 144 : string semaphore = (i==0 ? (provider_name+"_") : "") + probe_name + "_semaphore";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ # # ]
6409 : : // XXX: multiple addresses?
6410 [ - + ]: 144 : if (sess.verbose > 2)
6411 [ # # ][ # # ]: 0 : clog << _F("looking for semaphore symbol %s ", semaphore.c_str());
[ # # ][ # # ]
6412 : :
6413 : : Dwarf_Addr addr;
6414 [ - + ]: 144 : if (this->semaphore)
6415 : 0 : addr = this->semaphore;
6416 : : else
6417 [ + - ][ + - ]: 144 : addr = lookup_symbol_address(dw.module, semaphore.c_str());
6418 [ - + ]: 144 : if (addr)
6419 : : {
6420 [ # # ][ # # ]: 0 : if (dwfl_module_relocations (dw.module) > 0)
6421 [ # # ]: 0 : dwfl_module_relocate_address (dw.module, &addr);
6422 : : // XXX: relocation basis?
6423 : :
6424 : : // Dyninst needs the *file*-based offset for semaphores,
6425 : : // so subtract the difference in load addresses between .text and .probes
6426 [ # # ]: 0 : if (dw.sess.runtime_usermode_p())
6427 : 0 : addr -= semaphore_load_offset;
6428 : :
6429 [ # # ]: 0 : for (unsigned i = start; i < results.size(); ++i)
6430 : 0 : results[i]->sdt_semaphore_addr = addr;
6431 [ # # ]: 0 : if (sess.verbose > 2)
6432 [ # # ][ # # ]: 0 : clog << _(", found at 0x") << hex << addr << dec << endl;
[ # # ][ # # ]
[ # # ]
6433 : 72 : return;
6434 : : }
6435 : : else
6436 [ - + ]: 144 : if (sess.verbose > 2)
6437 [ # # ][ # # ]: 144 : clog << _(", not found") << endl;
6438 [ + - ][ + - ]: 144 : }
6439 : : }
6440 : :
6441 : :
6442 : : void
6443 : 0 : sdt_query::convert_probe (probe *base)
6444 : : {
6445 [ # # ]: 0 : block *b = new block;
6446 : 0 : b->tok = base->body->tok;
6447 : :
6448 : : // Generate: if (arg1 != mark("label")) next;
6449 [ # # ]: 0 : functioncall *fc = new functioncall;
6450 : 0 : fc->function = "ulong_arg";
6451 : 0 : fc->tok = b->tok;
6452 [ # # ]: 0 : literal_number* num = new literal_number(1);
6453 : 0 : num->tok = b->tok;
6454 [ # # ]: 0 : fc->args.push_back(num);
6455 : :
6456 [ # # ]: 0 : functioncall *fcus = new functioncall;
6457 : 0 : fcus->function = "user_string";
6458 : 0 : fcus->type = pe_string;
6459 : 0 : fcus->tok = b->tok;
6460 [ # # ]: 0 : fcus->args.push_back(fc);
6461 : :
6462 [ # # ]: 0 : if_statement *is = new if_statement;
6463 [ # # ]: 0 : is->thenblock = new next_statement;
6464 : 0 : is->elseblock = NULL;
6465 : 0 : is->tok = b->tok;
6466 : 0 : is->thenblock->tok = b->tok;
6467 [ # # ]: 0 : comparison *be = new comparison;
6468 : 0 : be->op = "!=";
6469 : 0 : be->tok = b->tok;
6470 : 0 : be->left = fcus;
6471 [ # # ]: 0 : be->right = new literal_string(probe_name);
6472 : 0 : be->right->tok = b->tok;
6473 : 0 : is->condition = be;
6474 [ # # ]: 0 : b->statements.push_back(is);
6475 : :
6476 : : // Now replace the body
6477 : 0 : b->statements.push_back(base->body);
6478 : 0 : base->body = b;
6479 : 0 : }
6480 : :
6481 : :
6482 : : probe*
6483 : 72 : sdt_query::convert_location ()
6484 : : {
6485 [ + - ][ + - ]: 72 : probe_point* specific_loc = new probe_point(*base_loc);
6486 [ + - ]: 72 : vector<probe_point::component*> derived_comps;
6487 : :
6488 : 72 : vector<probe_point::component*>::iterator it;
6489 [ + - ][ + - ]: 432 : for (it = specific_loc->components.begin();
[ + + ]
6490 [ + - ]: 216 : it != specific_loc->components.end(); ++it)
6491 [ + - ][ + + ]: 144 : if ((*it)->functor == TOK_PROCESS)
6492 : : {
6493 : : // copy the process name
6494 [ + - ]: 72 : derived_comps.push_back(*it);
6495 : : }
6496 [ + - ][ - + ]: 72 : else if ((*it)->functor == TOK_LIBRARY)
6497 : : {
6498 : : // copy the library name for process probes
6499 [ # # ]: 0 : derived_comps.push_back(*it);
6500 : : }
6501 [ + - ][ - + ]: 72 : else if ((*it)->functor == TOK_PROVIDER)
6502 : : {
6503 : : // replace the possibly wildcarded arg with the specific provider name
6504 : 0 : *it = new probe_point::component(TOK_PROVIDER,
6505 [ # # ][ # # ]: 0 : new literal_string(provider_name));
[ # # ][ # # ]
6506 : : }
6507 [ + - ][ + - ]: 72 : else if ((*it)->functor == TOK_MARK)
6508 : : {
6509 : : // replace the possibly wildcarded arg with the specific marker name
6510 : 72 : *it = new probe_point::component(TOK_MARK,
6511 [ + - ][ + - ]: 72 : new literal_string(probe_name));
[ + - ][ + - ]
6512 : :
6513 [ - + ]: 72 : if (sess.verbose > 3)
6514 [ # # # # ]: 0 : switch (probe_type)
6515 : : {
6516 : : case uprobe1_type:
6517 [ # # ]: 0 : clog << _("probe_type == uprobe1, use statement addr: 0x")
6518 [ # # ][ # # ]: 0 : << hex << pc << dec << endl;
[ # # ][ # # ]
6519 : 0 : break;
6520 : : case uprobe2_type:
6521 [ # # ]: 0 : clog << _("probe_type == uprobe2, use statement addr: 0x")
6522 [ # # ][ # # ]: 0 : << hex << pc << dec << endl;
[ # # ][ # # ]
6523 : 0 : break;
6524 : : case uprobe3_type:
6525 [ # # ]: 0 : clog << _("probe_type == uprobe3, use statement addr: 0x")
6526 [ # # ][ # # ]: 0 : << hex << pc << dec << endl;
[ # # ][ # # ]
6527 : 0 : break;
6528 : : default:
6529 [ # # ][ # # ]: 0 : clog << _F("probe_type == use_uprobe_no_dwarf, use label name: _stapprobe1_%s",
[ # # ][ # # ]
6530 [ # # ]: 0 : pp_mark.c_str()) << endl;
6531 : : }
6532 : :
6533 [ + - ]: 72 : switch (probe_type)
6534 : : {
6535 : : case uprobe1_type:
6536 : : case uprobe2_type:
6537 : : case uprobe3_type:
6538 : : // process("executable").statement(probe_arg)
6539 : : derived_comps.push_back
6540 : : (new probe_point::component(TOK_STATEMENT,
6541 [ + - ][ + - ]: 72 : new literal_number(pc, true)));
[ + - ][ + - ]
[ + - ]
6542 : 72 : break;
6543 : :
6544 : : default: // deprecated
6545 : : // process("executable").function("*").label("_stapprobe1_MARK_NAME")
6546 : : derived_comps.push_back
6547 : : (new probe_point::component(TOK_FUNCTION,
6548 [ # # ][ # # ]: 0 : new literal_string("*")));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6549 : : derived_comps.push_back
6550 : : (new probe_point::component(TOK_LABEL,
6551 [ # # ][ # # ]: 0 : new literal_string("_stapprobe1_" + pp_mark)));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
6552 : 72 : break;
6553 : : }
6554 : : }
6555 : :
6556 [ + - ][ + - ]: 72 : probe_point* derived_loc = new probe_point(*specific_loc);
6557 [ + - ]: 72 : derived_loc->components = derived_comps;
6558 [ + - ][ + - ]: 72 : return base_probe->create_alias(derived_loc, specific_loc);
6559 : : }
6560 : :
6561 : :
6562 : : void
6563 : 0 : sdt_query::query_library (const char *library)
6564 : : {
6565 [ # # ]: 0 : query_one_library (library, dw, user_lib, base_probe, base_loc, results);
6566 : 0 : }
6567 : :
6568 : :
6569 : : void
6570 : 46880 : dwarf_builder::build(systemtap_session & sess,
6571 : : probe * base,
6572 : : probe_point * location,
6573 : : literal_map_t const & parameters,
6574 : : vector<derived_probe *> & finished_results)
6575 : : {
6576 : : // NB: the kernel/user dwlfpp objects are long-lived.
6577 : : // XXX: but they should be per-session, as this builder object
6578 : : // may be reused if we try to cross-instrument multiple targets.
6579 : :
6580 : 46880 : dwflpp* dw = 0;
6581 [ + - ]: 46880 : literal_map_t filled_parameters = parameters;
6582 : :
6583 [ + - ]: 46880 : string module_name;
6584 [ + - ][ + + ]: 46880 : if (has_null_param (parameters, TOK_KERNEL))
6585 : : {
6586 [ + - ][ + + ]: 44801 : dw = get_kern_dw(sess, "kernel");
[ + - ]
6587 : : }
6588 [ + - ][ + + ]: 2079 : else if (get_param (parameters, TOK_MODULE, module_name))
6589 : : {
6590 : 1999 : size_t dash_pos = 0;
6591 [ + - ][ + + ]: 2011 : while((dash_pos=module_name.find('-'))!=string::npos)
6592 [ + - ]: 12 : module_name.replace(int(dash_pos),1,"_");
6593 [ + - ][ + - ]: 1999 : filled_parameters[TOK_MODULE] = new literal_string(module_name);
[ + - ]
6594 : : // NB: glob patterns get expanded later, during the offline
6595 : : // elfutils module listing.
6596 [ + - ]: 1999 : dw = get_kern_dw(sess, module_name);
6597 : : }
6598 [ + - ][ + + ]: 80 : else if (get_param (parameters, TOK_PROCESS, module_name) || has_null_param(parameters, TOK_PROCESS))
[ + - ][ + - ]
[ + - ]
6599 : : {
6600 [ + - ][ + - ]: 80 : module_name = sess.sysroot + module_name;
[ + - ]
6601 [ + - ][ + + ]: 80 : if(has_null_param(filled_parameters, TOK_PROCESS))
6602 : : {
6603 : : wordexp_t words;
6604 [ + - ][ + - ]: 6 : int rc = wordexp(sess.cmd.c_str(), &words, WRDE_NOCMD|WRDE_UNDEF);
6605 [ + - ][ + + ]: 6 : if(rc || words.we_wordc <= 0)
6606 [ + - ][ + - ]: 1 : throw semantic_error(_("unspecified process probe is invalid without a -c COMMAND"));
6607 [ + - ][ + - ]: 5 : module_name = sess.sysroot + words.we_wordv[0];
[ + - ]
6608 [ + - ][ + - ]: 5 : filled_parameters[TOK_PROCESS] = new literal_string(module_name);// this needs to be used in place of the blank map
[ + - ]
6609 : : // in the case of TOK_MARK we need to modify locations as well
6610 [ + - ]: 10 : if(location->components[0]->functor==TOK_PROCESS &&
[ + - + - ]
[ + - ]
6611 : 5 : location->components[0]->arg == 0)
6612 [ + - ][ + - ]: 6 : location->components[0]->arg = new literal_string(module_name);
6613 : 5 : wordfree (& words);
6614 : : }
6615 : :
6616 : : // PR6456 process("/bin/*") glob handling
6617 [ + - ][ + + ]: 79 : if (contains_glob_chars (module_name))
6618 : : {
6619 : : // Expand glob via rewriting the probe-point process("....")
6620 : : // parameter, asserted to be the first one.
6621 : :
6622 [ - + ]: 12 : assert (location->components.size() > 0);
6623 [ + - ][ - + ]: 12 : assert (location->components[0]->functor == TOK_PROCESS);
6624 [ - + ]: 12 : assert (location->components[0]->arg);
6625 [ - + ]: 12 : literal_string* lit = dynamic_cast<literal_string*>(location->components[0]->arg);
6626 [ - + ]: 12 : assert (lit);
6627 : :
6628 : : // Evaluate glob here, and call derive_probes recursively with each match.
6629 : : glob_t the_blob;
6630 [ + - ]: 12 : int rc = glob (module_name.c_str(), 0, NULL, & the_blob);
6631 [ - + ]: 12 : if (rc)
6632 [ # # ][ # # ]: 0 : throw semantic_error (_F("glob %s error (%s)", module_name.c_str(), lex_cast(rc).c_str() ));
[ # # ][ # # ]
[ # # ]
6633 [ + + ]: 29 : for (unsigned i = 0; i < the_blob.gl_pathc; ++i)
6634 : : {
6635 [ + - ]: 17 : assert_no_interrupts();
6636 : :
6637 : 17 : const char* globbed = the_blob.gl_pathv[i];
6638 : : struct stat st;
6639 : :
6640 [ + + + - ]: 31 : if (access (globbed, X_OK) == 0
[ + - ][ + + ]
6641 : 14 : && stat (globbed, &st) == 0
6642 : : && S_ISREG (st.st_mode)) // see find_executable()
6643 : : {
6644 : : // Need to call canonicalize here, in order to path-expand
6645 : : // patterns like process("stap*"). Otherwise it may go through
6646 : : // to the next round of expansion as ("stap"), leading to a $PATH
6647 : : // search that's not consistent with the glob search already done.
6648 : :
6649 : 14 : char *cf = canonicalize_file_name (globbed);
6650 [ + - ]: 14 : if (cf) globbed = cf;
6651 : :
6652 : : // synthesize a new probe_point, with the glob-expanded string
6653 [ + - ][ + - ]: 14 : probe_point *pp = new probe_point (*location);
6654 : : // PR13338: quote results to prevent recursion
6655 [ + - ][ + - ]: 14 : string eglobbed = escape_glob_chars (globbed);
[ + - ]
6656 : :
6657 [ + + ]: 14 : if (sess.verbose > 1)
6658 [ + - ][ + - ]: 6 : clog << _F("Expanded process(\"%s\") to process(\"%s\")",
[ + - ][ + - ]
[ + - ]
6659 [ + - ]: 3 : module_name.c_str(), eglobbed.c_str()) << endl;
6660 [ + - ]: 14 : string eglobbed_tgt = path_remove_sysroot(sess, eglobbed);
6661 : :
6662 : : probe_point::component* ppc = new probe_point::component (TOK_PROCESS,
6663 [ + - ][ + - ]: 14 : new literal_string (eglobbed_tgt));
[ + - ][ + - ]
6664 : 14 : ppc->tok = location->components[0]->tok; // overwrite [0] slot, pattern matched above
6665 : 14 : pp->components[0] = ppc;
6666 : :
6667 [ + - ][ + - ]: 14 : probe* new_probe = new probe (*base, pp);
6668 : :
6669 : : // We override "optional = true" here, as if the
6670 : : // wildcarded probe point was given a "?" suffix.
6671 : :
6672 : : // This is because wildcard probes will be expected
6673 : : // by users to apply only to some subset of the
6674 : : // matching binaries, in the sense of "any", rather
6675 : : // than "all", sort of similarly how
6676 : : // module("*").function("...") patterns work.
6677 : :
6678 : : derive_probes (sess, new_probe, finished_results,
6679 [ + - ][ + - ]: 14 : true /* NB: not location->optional */ );
[ + - ]
6680 : : }
6681 : : }
6682 : :
6683 : 12 : globfree (& the_blob);
6684 : : return; // avoid falling through
6685 : : }
6686 : :
6687 : : // PR13338: unquote glob results
6688 [ + - ][ + - ]: 67 : module_name = unescape_glob_chars (module_name);
[ + - ]
6689 [ + - ][ + - ]: 67 : user_path = find_executable (module_name, "", sess.sysenv); // canonicalize it
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
6690 : :
6691 : : // if the executable starts with "#!", we look for the interpreter of the script
6692 : : {
6693 [ + - ][ + - ]: 67 : ifstream script_file (user_path.c_str () );
6694 : :
6695 [ + - ][ + + ]: 67 : if (script_file.good ())
6696 : : {
6697 [ + - ]: 60 : string line;
6698 : :
6699 [ + - ]: 60 : getline (script_file, line);
6700 : :
6701 [ + - ][ + + ]: 60 : if (line.compare (0, 2, "#!") == 0)
6702 : : {
6703 [ + - ]: 1 : string path_head = line.substr(2);
6704 : :
6705 : : // remove white spaces at the beginning of the string
6706 [ + - ]: 1 : size_t p2 = path_head.find_first_not_of(" \t");
6707 : :
6708 [ + - ]: 1 : if (p2 != string::npos)
6709 : : {
6710 [ + - ]: 1 : string path = path_head.substr(p2);
6711 : :
6712 : : // remove white spaces at the end of the string
6713 [ + - ]: 1 : p2 = path.find_last_not_of(" \t\n");
6714 [ + - ]: 1 : if (string::npos != p2)
6715 [ + - ]: 1 : path.erase(p2+1);
6716 : :
6717 : : // handle "#!/usr/bin/env" redirect
6718 : 1 : size_t offset = 0;
6719 [ + - ][ - + ]: 1 : if (path.compare(0, sizeof("/bin/env")-1, "/bin/env") == 0)
6720 : : {
6721 : 0 : offset = sizeof("/bin/env")-1;
6722 : : }
6723 [ + - ][ - + ]: 1 : else if (path.compare(0, sizeof("/usr/bin/env")-1, "/usr/bin/env") == 0)
6724 : : {
6725 : 0 : offset = sizeof("/usr/bin/env")-1;
6726 : : }
6727 : :
6728 [ - + ]: 1 : if (offset != 0)
6729 : : {
6730 [ # # ]: 0 : size_t p3 = path.find_first_not_of(" \t", offset);
6731 : :
6732 [ # # ]: 0 : if (p3 != string::npos)
6733 : : {
6734 [ # # ]: 0 : string env_path = path.substr(p3);
6735 : : user_path = find_executable (env_path, sess.sysroot,
6736 [ # # ][ # # ]: 0 : sess.sysenv);
[ # # ][ # # ]
[ # # ][ # # ]
6737 : : }
6738 : : }
6739 : : else
6740 : : {
6741 [ + - ][ + - ]: 1 : user_path = find_executable (path, sess.sysroot, sess.sysenv);
[ + - ][ + - ]
[ + - ]
6742 : : }
6743 : :
6744 : : struct stat st;
6745 : :
6746 [ + - ]: 2 : if (access (user_path.c_str(), X_OK) == 0
[ + - + - ]
[ + - ][ + - ]
6747 [ + - ]: 1 : && stat (user_path.c_str(), &st) == 0
6748 : : && S_ISREG (st.st_mode)) // see find_executable()
6749 : : {
6750 [ - + ]: 1 : if (sess.verbose > 1)
6751 [ # # ][ # # ]: 0 : clog << _F("Expanded process(\"%s\") to process(\"%s\")",
[ # # ][ # # ]
[ # # ]
6752 [ # # ]: 0 : module_name.c_str(), user_path.c_str()) << endl;
6753 : :
6754 [ - + ]: 1 : assert (location->components.size() > 0);
6755 [ + - ][ - + ]: 1 : assert (location->components[0]->functor == TOK_PROCESS);
6756 [ - + ]: 1 : assert (location->components[0]->arg);
6757 [ - + ]: 1 : literal_string* lit = dynamic_cast<literal_string*>(location->components[0]->arg);
6758 [ - + ]: 1 : assert (lit);
6759 : :
6760 : : // synthesize a new probe_point, with the expanded string
6761 [ + - ][ + - ]: 1 : probe_point *pp = new probe_point (*location);
6762 [ + - ]: 1 : string user_path_tgt = path_remove_sysroot(sess, user_path);
6763 : : probe_point::component* ppc = new probe_point::component (TOK_PROCESS,
6764 [ + - ][ + - ]: 1 : new literal_string (user_path_tgt.c_str()));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
6765 : 1 : ppc->tok = location->components[0]->tok; // overwrite [0] slot, pattern matched above
6766 : 1 : pp->components[0] = ppc;
6767 : :
6768 [ + - ][ + - ]: 1 : probe* new_probe = new probe (*base, pp);
6769 : :
6770 [ + - ]: 1 : derive_probes (sess, new_probe, finished_results);
6771 : :
6772 [ + - ]: 1 : script_file.close();
6773 [ + - ]: 1 : return;
6774 [ + - ][ - + ]: 1 : }
6775 [ + - ][ - + ]: 60 : }
6776 [ + - ][ + + ]: 60 : }
6777 : : }
6778 [ + - ][ + - ]: 67 : script_file.close();
[ + + ]
6779 : : }
6780 : :
6781 [ + - ][ + + ]: 91 : if (get_param (parameters, TOK_LIBRARY, user_lib)
[ + - ][ + + ]
[ + + ]
6782 [ + - ][ + - ]: 24 : && user_lib.length() && ! contains_glob_chars (user_lib))
6783 : : {
6784 : : module_name = find_executable (user_lib, sess.sysroot, sess.sysenv,
6785 [ + - ][ + - ]: 11 : "LD_LIBRARY_PATH");
[ + - ][ + - ]
[ + - ]
6786 [ + - ][ - + ]: 11 : if (module_name.find('/') == string::npos)
6787 : : // We didn't find user_lib so use iterate_over_libraries
6788 [ # # ]: 0 : module_name = user_path;
6789 : : }
6790 : : else
6791 [ + - ]: 55 : module_name = user_path; // canonicalize it
6792 : :
6793 : : // uretprobes aren't available everywhere
6794 [ + - ][ + + ]: 66 : if (has_null_param(parameters, TOK_RETURN) && !sess.runtime_usermode_p())
[ + - ][ + + ]
6795 : : {
6796 [ + - ][ - + ]: 1 : if (kernel_supports_inode_uprobes(sess) &&
[ # # ][ - + ]
6797 [ # # ]: 0 : !kernel_supports_inode_uretprobes(sess))
6798 : : throw semantic_error
6799 [ # # ][ # # ]: 0 : (_("process return probes not available [man error::inode-uprobes]"));
6800 : : }
6801 : :
6802 : : // There is a similar check in pass 4 (buildrun), but it is
6803 : : // needed here too to make sure alternatives for optional
6804 : : // (? or !) process probes are disposed and/or alternatives
6805 : : // are selected.
6806 [ + - ]: 66 : if (!sess.runtime_usermode_p())
6807 [ + + ]: 66 : check_process_probe_kernel_support(sess);
6808 : :
6809 : : // user-space target; we use one dwflpp instance per module name
6810 : : // (= program or shared library)
6811 [ + - ]: 64 : dw = get_user_dw(sess, module_name);
6812 : : }
6813 : :
6814 [ - + ]: 46862 : if (sess.verbose > 3)
6815 [ # # ][ # # ]: 0 : clog << _F("dwarf_builder::build for %s", module_name.c_str()) << endl;
[ # # ][ # # ]
[ # # ]
6816 : :
6817 [ + - ]: 46862 : string dummy_mark_name; // NB: PR10245: dummy value, need not substitute - => __
6818 [ + - ][ + + ]: 46862 : if (get_param(parameters, TOK_MARK, dummy_mark_name))
6819 : : {
6820 [ - + ]: 16 : assert(dw);
6821 [ + - ][ + - ]: 16 : sdt_query sdtq(base, location, *dw, filled_parameters, finished_results, user_lib);
[ + - ]
6822 [ + - ]: 16 : dw->iterate_over_modules(&query_module, &sdtq);
6823 [ + - ]: 16 : return;
6824 : : }
6825 : :
6826 : 46846 : unsigned results_pre = finished_results.size();
6827 [ + - ][ + - ]: 46846 : dwarf_query q(base, location, *dw, filled_parameters, finished_results, user_path, user_lib);
[ + - ][ + - ]
[ + - ]
6828 : :
6829 : : // XXX: kernel.statement.absolute is a special case that requires no
6830 : : // dwfl processing. This code should be in a separate builder.
6831 [ + + ][ + + ]: 46846 : if (q.has_kernel && q.has_absolute)
6832 : : {
6833 : : // assert guru mode for absolute probes
6834 [ + + ]: 5 : if (! q.base_probe->privileged)
6835 : : {
6836 : 1 : throw semantic_error (_("absolute statement probe in unprivileged script; need stap -g"),
6837 [ + - ][ + - ]: 1 : q.base_probe->tok);
6838 : : }
6839 : :
6840 : : // For kernel.statement(NUM).absolute probe points, we bypass
6841 : : // all the debuginfo stuff: We just wire up a
6842 : : // dwarf_derived_probe right here and now.
6843 : : dwarf_derived_probe* p =
6844 : : new dwarf_derived_probe ("", "", 0, "kernel", "",
6845 : : q.statement_num_val, q.statement_num_val,
6846 [ + - ][ + - ]: 4 : q, 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
6847 [ + - ]: 4 : finished_results.push_back (p);
6848 [ + - ][ + - ]: 4 : sess.unwindsym_modules.insert ("kernel");
[ + - ]
6849 : : return;
6850 : : }
6851 : :
6852 [ + - ]: 46841 : dw->iterate_over_modules(&query_module, &q);
6853 : :
6854 : :
6855 : : // PR11553 special processing: .return probes requested, but
6856 : : // some inlined function instances matched.
6857 [ + - ]: 46841 : unsigned i_n_r = q.inlined_non_returnable.size();
6858 : 46841 : unsigned results_post = finished_results.size();
6859 [ + + ]: 46841 : if (i_n_r > 0)
6860 : : {
6861 [ + + ][ + + ]: 138 : if ((results_pre == results_post) && (! sess.suppress_warnings)) // no matches; issue warning
6862 : : {
6863 [ + - ]: 6 : string quicklist;
6864 [ + - ][ + + ]: 24 : for (set<string>::iterator it = q.inlined_non_returnable.begin();
6865 [ + - ]: 12 : it != q.inlined_non_returnable.end();
6866 : : it++)
6867 : : {
6868 [ + - ][ + - ]: 6 : quicklist += " " + (*it);
[ + - ]
6869 [ + - ][ - + ]: 6 : if (quicklist.size() > 80) // heuristic, don't make an overlong report line
6870 : : {
6871 [ # # ]: 0 : quicklist += " ...";
6872 : 0 : break;
6873 : : }
6874 : : }
6875 : :
6876 [ + - ]: 6 : sess.print_warning (_F(ngettext("cannot probe .return of %u inlined function %s",
6877 : : "cannot probe .return of %u inlined functions %s",
6878 [ + - ][ + - ]: 6 : quicklist.size()), i_n_r, quicklist.c_str()));
[ + - ][ + - ]
[ + - ]
6879 : : // There will be also a "no matches" semantic error generated.
6880 : : }
6881 [ - + ]: 138 : if (sess.verbose > 1)
6882 [ # # ][ # # ]: 0 : clog << _F(ngettext("skipped .return probe of %u inlined function",
[ # # ]
6883 [ # # ]: 0 : "skipped .return probe of %u inlined functions", i_n_r), i_n_r) << endl;
6884 [ + - ][ - + ]: 138 : if ((sess.verbose > 3) || (sess.verbose > 2 && results_pre == results_post)) // issue details with high verbosity
[ # # ]
6885 : : {
6886 [ # # ][ # # ]: 0 : for (set<string>::iterator it = q.inlined_non_returnable.begin();
6887 [ # # ]: 0 : it != q.inlined_non_returnable.end();
6888 : : it++)
6889 [ # # ][ # # ]: 0 : clog << (*it) << " ";
6890 [ # # ]: 46841 : clog << endl;
6891 : : }
6892 [ + - ][ + + ]: 46880 : } // i_n_r > 0
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ][ + + ]
6893 : : }
6894 : :
6895 : 2247 : symbol_table::~symbol_table()
6896 : : {
6897 [ + - ]: 749 : delete_map(map_by_addr);
6898 [ + - ]: 749 : }
6899 : :
6900 : : void
6901 : 10062711 : symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
6902 : : Dwarf_Addr addr, Dwarf_Addr */*high_addr*/)
6903 : : {
6904 : : #ifdef __powerpc__
6905 : : // Map ".sys_foo" to "sys_foo".
6906 : : if (name[0] == '.')
6907 : : name++;
6908 : : #endif
6909 [ + - ]: 10062711 : func_info *fi = new func_info();
6910 : 10062711 : fi->addr = addr;
6911 : 10062711 : fi->name = name;
6912 : 10062711 : fi->weak = weak;
6913 : 10062711 : fi->descriptor = descriptor;
6914 : 10062711 : map_by_name[fi->name] = fi;
6915 : : // TODO: Use a multimap in case there are multiple static
6916 : : // functions with the same name?
6917 [ + - ]: 10062711 : map_by_addr.insert(make_pair(addr, fi));
6918 : 10062711 : }
6919 : :
6920 : : enum info_status
6921 : 0 : symbol_table::read_symbols(FILE *f, const string& path)
6922 : : {
6923 : : // Based on do_kernel_symbols() in runtime/staprun/symbols.c
6924 : : int ret;
6925 : 0 : char *name = 0;
6926 : 0 : char *mod = 0;
6927 : : char type;
6928 : : unsigned long long addr;
6929 : 0 : Dwarf_Addr high_addr = 0;
6930 : 0 : int line = 0;
6931 : :
6932 : : #if __GLIBC__ >2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)
6933 : : #define MS_FMT "%ms"
6934 : : #else
6935 : : #define MS_FMT "%as"
6936 : : #endif
6937 : : // %ms (newer than %as) mallocs space for the string and stores its address.
6938 [ # # ][ # # ]: 0 : while ((ret = fscanf(f, "%llx %c " MS_FMT " [" MS_FMT, &addr, &type, &name, &mod)) > 0)
6939 : : {
6940 : 0 : auto_free free_name(name);
6941 : 0 : auto_free free_mod(mod);
6942 : 0 : line++;
6943 [ # # ]: 0 : if (ret < 3)
6944 : : {
6945 [ # # ][ # # ]: 0 : cerr << _F("Symbol table error: Line %d of symbol list from %s is not in correct format: address type name [module]\n",
[ # # ]
6946 [ # # ]: 0 : line, path.c_str());
6947 : : // Caller should delete symbol_table object.
6948 : 0 : return info_absent;
6949 : : }
6950 [ # # ]: 0 : else if (ret > 3)
6951 : : {
6952 : : // Modules are loaded above the kernel, so if we're getting
6953 : : // modules, we're done.
6954 : : break;
6955 : : }
6956 [ # # ][ # # ]: 0 : if (type == 'T' || type == 't' || type == 'W')
[ # # ]
6957 [ # # ]: 0 : add_symbol(name, (type == 'W'), false, (Dwarf_Addr) addr, &high_addr);
6958 [ # # # ]: 0 : }
[ # # # ]
6959 : :
6960 [ # # ][ # # ]: 0 : if (map_by_addr.size() < 1)
6961 : : {
6962 [ # # ][ # # ]: 0 : cerr << _F("Symbol table error: %s contains no function symbols.\n",
[ # # ][ # # ]
6963 [ # # ]: 0 : path.c_str()) << endl;
6964 : 0 : return info_absent;
6965 : : }
6966 : 0 : return info_present;
6967 : : }
6968 : :
6969 : : // NB: This currently unused. We use get_from_elf() instead because
6970 : : // that gives us raw addresses -- which we need for modules -- whereas
6971 : : // nm provides the address relative to the beginning of the section.
6972 : : enum info_status
6973 : 0 : symbol_table::read_from_elf_file(const string &path,
6974 : : systemtap_session &sess)
6975 : : {
6976 [ # # ]: 0 : vector<string> cmd;
6977 [ # # ][ # # ]: 0 : cmd.push_back("/usr/bin/nm");
[ # # ]
6978 [ # # ][ # # ]: 0 : cmd.push_back("-n");
[ # # ]
6979 [ # # ][ # # ]: 0 : cmd.push_back("--defined-only");
[ # # ]
6980 [ # # ][ # # ]: 0 : cmd.push_back("path");
[ # # ]
6981 : :
6982 : : FILE *f;
6983 : : int child_fd;
6984 [ # # ]: 0 : pid_t child = stap_spawn_piped(sess.verbose, cmd, NULL, &child_fd);
6985 [ # # ][ # # ]: 0 : if (child <= 0 || !(f = fdopen(child_fd, "r")))
[ # # ]
6986 : : {
6987 : : // nm failures are detected by stap_waitpid
6988 [ # # ][ # # ]: 0 : cerr << _F("Internal error reading symbol table from %s -- %s\n",
[ # # ]
6989 [ # # ]: 0 : path.c_str(), strerror(errno));
6990 : 0 : return info_absent;
6991 : : }
6992 [ # # ]: 0 : enum info_status status = read_symbols(f, path);
6993 [ # # ][ # # ]: 0 : if (fclose(f) || stap_waitpid(sess.verbose, child))
[ # # ][ # # ]
[ # # ]
6994 : : {
6995 [ # # ]: 0 : if (status == info_present)
6996 [ # # ][ # # ]: 0 : sess.print_warning("nm cannot read symbol table from " + path);
[ # # ]
6997 : 0 : return info_absent;
6998 : : }
6999 [ # # ]: 0 : return status;
7000 : : }
7001 : :
7002 : : enum info_status
7003 : 0 : symbol_table::read_from_text_file(const string& path,
7004 : : systemtap_session &sess)
7005 : : {
7006 : 0 : FILE *f = fopen(path.c_str(), "r");
7007 [ # # ]: 0 : if (!f)
7008 : : {
7009 [ # # ][ # # ]: 0 : sess.print_warning("cannot read symbol table from " + path + " -- " + strerror(errno));
[ # # ][ # # ]
[ # # ]
7010 : 0 : return info_absent;
7011 : : }
7012 : 0 : enum info_status status = read_symbols(f, path);
7013 : 0 : (void) fclose(f);
7014 : 0 : return status;
7015 : : }
7016 : :
7017 : : void
7018 : 749 : symbol_table::prepare_section_rejection(Dwfl_Module *mod __attribute__ ((unused)))
7019 : : {
7020 : : #ifdef __powerpc__
7021 : : /*
7022 : : * The .opd section contains function descriptors that can look
7023 : : * just like function entry points. For example, there's a function
7024 : : * descriptor called "do_exit" that links to the entry point ".do_exit".
7025 : : * Reject all symbols in .opd.
7026 : : */
7027 : : opd_section = SHN_UNDEF;
7028 : : Dwarf_Addr bias;
7029 : : Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
7030 : : ?: dwfl_module_getelf (mod, &bias));
7031 : : Elf_Scn* scn = 0;
7032 : : size_t shstrndx;
7033 : :
7034 : : if (!elf)
7035 : : return;
7036 : : if (elf_getshdrstrndx (elf, &shstrndx) != 0)
7037 : : return;
7038 : : while ((scn = elf_nextscn(elf, scn)) != NULL)
7039 : : {
7040 : : GElf_Shdr shdr_mem;
7041 : : GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
7042 : : if (!shdr)
7043 : : continue;
7044 : : const char *name = elf_strptr(elf, shstrndx, shdr->sh_name);
7045 : : if (!strcmp(name, ".opd"))
7046 : : {
7047 : : opd_section = elf_ndxscn(scn);
7048 : : return;
7049 : : }
7050 : : }
7051 : : #endif
7052 : 749 : }
7053 : :
7054 : : bool
7055 : 10062711 : symbol_table::reject_section(GElf_Word section)
7056 : : {
7057 [ + + ]: 10062711 : if (section == SHN_UNDEF)
7058 : 3302 : return true;
7059 : : #ifdef __powerpc__
7060 : : if (section == opd_section)
7061 : : return true;
7062 : : #endif
7063 : 10062711 : return false;
7064 : : }
7065 : :
7066 : : enum info_status
7067 : 749 : symbol_table::get_from_elf()
7068 : : {
7069 : 749 : Dwarf_Addr high_addr = 0;
7070 : 749 : Dwfl_Module *mod = mod_info->mod;
7071 [ + - ]: 749 : int syments = dwfl_module_getsymtab(mod);
7072 [ - + ]: 749 : assert(syments);
7073 : 749 : prepare_section_rejection(mod);
7074 [ + + ]: 42915607 : for (int i = 1; i < syments; ++i)
7075 : : {
7076 : : GElf_Sym sym;
7077 : : GElf_Word section;
7078 [ + - ]: 42914858 : const char *name = dwfl_module_getsym(mod, i, &sym, §ion);
7079 [ + - ][ + + ]: 42914858 : if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC)
7080 : : add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
7081 [ + - ]: 10062711 : reject_section(section), sym.st_value, &high_addr);
7082 : : }
7083 : 749 : return info_present;
7084 : : }
7085 : :
7086 : : func_info *
7087 : 0 : symbol_table::get_func_containing_address(Dwarf_Addr addr)
7088 : : {
7089 [ # # ]: 0 : iterator_t iter = map_by_addr.upper_bound(addr);
7090 [ # # ][ # # ]: 0 : if (iter == map_by_addr.begin())
7091 : 0 : return NULL;
7092 : : else
7093 [ # # ]: 0 : return (--iter)->second;
7094 : : }
7095 : :
7096 : : func_info *
7097 : 0 : symbol_table::get_first_func()
7098 : : {
7099 [ # # ]: 0 : iterator_t iter = map_by_addr.begin();
7100 [ # # ]: 0 : return (iter)->second;
7101 : : }
7102 : :
7103 : : func_info *
7104 : 20903500 : symbol_table::lookup_symbol(const string& name)
7105 : : {
7106 [ + - ]: 20903500 : map<string, func_info*>::iterator i = map_by_name.find(name);
7107 [ + - ][ + + ]: 20903500 : if (i == map_by_name.end())
7108 : 238454 : return NULL;
7109 [ + - ]: 20903500 : return i->second;
7110 : : }
7111 : :
7112 : : Dwarf_Addr
7113 : 400 : symbol_table::lookup_symbol_address(const string& name)
7114 : : {
7115 : 400 : func_info *fi = lookup_symbol(name);
7116 [ + - ]: 400 : if (fi)
7117 : 400 : return fi->addr;
7118 : 400 : return 0;
7119 : : }
7120 : :
7121 : : // This is the kernel symbol table. The kernel macro cond_syscall creates
7122 : : // a weak symbol for each system call and maps it to sys_ni_syscall.
7123 : : // For system calls not implemented elsewhere, this weak symbol shows up
7124 : : // in the kernel symbol table. Following the precedent of dwarfful stap,
7125 : : // we refuse to consider such symbols. Here we delete them from our
7126 : : // symbol table.
7127 : : // TODO: Consider generalizing this and/or making it part of blacklist
7128 : : // processing.
7129 : : void
7130 : 400 : symbol_table::purge_syscall_stubs()
7131 : : {
7132 [ + - ][ + - ]: 400 : Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
[ + - ]
7133 [ + - ]: 400 : if (stub_addr == 0)
7134 : 400 : return;
7135 [ + - ]: 400 : range_t purge_range = map_by_addr.equal_range(stub_addr);
7136 [ + + ]: 28800 : for (iterator_t iter = purge_range.first;
7137 : : iter != purge_range.second;
7138 : : )
7139 : : {
7140 [ + - ]: 28400 : func_info *fi = iter->second;
7141 [ + + ][ + - ]: 28400 : if (fi->weak && fi->name != "sys_ni_syscall")
[ + - ][ + + ]
7142 : : {
7143 [ + - ]: 28000 : map_by_name.erase(fi->name);
7144 [ + - ]: 28000 : map_by_addr.erase(iter++);
7145 [ + - ][ + - ]: 28000 : delete fi;
7146 : : }
7147 : : else
7148 : 400 : iter++;
7149 : : }
7150 : : }
7151 : :
7152 : : void
7153 : 46701 : module_info::get_symtab(dwarf_query *q)
7154 : : {
7155 [ + + ]: 46701 : if (symtab_status != info_unknown)
7156 : 45952 : return;
7157 : :
7158 [ + - ]: 749 : sym_table = new symbol_table(this);
7159 [ + - ]: 749 : if (!elf_path.empty())
7160 : : {
7161 : 749 : symtab_status = sym_table->get_from_elf();
7162 : : }
7163 : : else
7164 : : {
7165 [ # # ]: 0 : assert(name == TOK_KERNEL);
7166 : 0 : symtab_status = info_absent;
7167 : 0 : cerr << _("Error: Cannot find vmlinux.") << endl;;
7168 : : }
7169 [ - + ]: 749 : if (symtab_status == info_absent)
7170 : : {
7171 [ # # ]: 0 : delete sym_table;
7172 : 0 : sym_table = NULL;
7173 : 0 : return;
7174 : : }
7175 : :
7176 [ + + ]: 749 : if (name == TOK_KERNEL)
7177 : 46701 : sym_table->purge_syscall_stubs();
7178 : : }
7179 : :
7180 : : // update_symtab reconciles data between the elf symbol table and the dwarf
7181 : : // function enumeration. It updates the symbol table entries with the dwarf
7182 : : // die that describes the function, which also signals to query_module_symtab
7183 : : // that a statement probe isn't needed. In return, it also adds aliases to the
7184 : : // function table for names that share the same addr/die.
7185 : : void
7186 : 44573 : module_info::update_symtab(cu_function_cache_t *funcs)
7187 : : {
7188 [ + + ]: 44573 : if (!sym_table)
7189 : 44573 : return;
7190 : :
7191 [ + - ]: 41297 : cu_function_cache_t new_funcs;
7192 : :
7193 [ + - ][ + - ]: 72398544 : for (cu_function_cache_t::iterator func = funcs->begin();
[ + + ]
7194 [ + - ]: 36199272 : func != funcs->end(); func++)
7195 : : {
7196 : : // optimization: inlines will never be in the symbol table
7197 [ + - ][ + - ]: 36157975 : if (dwarf_func_inline(&func->second) != 0)
[ + + ]
7198 : 15254875 : continue;
7199 : :
7200 : : // XXX We may want to make additional efforts to match mangled elf names
7201 : : // to dwarf too. MIPS_linkage_name can help, but that's sometimes
7202 : : // missing, so we may also need to try matching by address. See also the
7203 : : // notes about _Z in dwflpp::iterate_over_functions().
7204 : :
7205 [ + - ][ + - ]: 20903100 : func_info *fi = sym_table->lookup_symbol(func->first);
7206 [ + + ]: 20903100 : if (!fi)
7207 : 238454 : continue;
7208 : :
7209 : : // iterate over all functions at the same address
7210 [ + - ]: 20664646 : symbol_table::range_t er = sym_table->map_by_addr.equal_range(fi->addr);
7211 [ + + ]: 56882623 : for (symbol_table::iterator_t it = er.first; it != er.second; ++it)
7212 : : {
7213 : : // update this function with the dwarf die
7214 [ + - ][ + - ]: 20724648 : it->second->die = func->second;
7215 : :
7216 : : // if this function is a new alias, then
7217 : : // save it to merge into the function cache
7218 [ + - ][ + + ]: 20724648 : if (it->second != fi)
7219 [ + - ][ + - ]: 60002 : new_funcs.insert(make_pair(it->second->name, it->second->die));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
7220 : : }
7221 : : }
7222 : :
7223 : : // add all discovered aliases back into the function cache
7224 : : // NB: this won't replace any names that dwarf may have already found
7225 [ + - ][ + - ]: 44573 : funcs->insert(new_funcs.begin(), new_funcs.end());
[ + - ][ + - ]
7226 : : }
7227 : :
7228 : 9292 : module_info::~module_info()
7229 : : {
7230 [ + + ]: 4646 : if (sym_table)
7231 [ + - ][ + - ]: 749 : delete sym_table;
7232 : 4646 : }
7233 : :
7234 : : // ------------------------------------------------------------------------
7235 : : // user-space probes
7236 : : // ------------------------------------------------------------------------
7237 : :
7238 : :
7239 [ # # ]: 27 : struct uprobe_derived_probe_group: public generic_dpg<uprobe_derived_probe>
7240 : : {
7241 : : private:
7242 : 12 : string make_pbm_key (uprobe_derived_probe* p) {
7243 [ + - ][ + - ]: 12 : return p->path + "|" + p->module + "|" + p->section + "|" + lex_cast(p->pid);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
7244 : : }
7245 : :
7246 : : void emit_module_maxuprobes (systemtap_session& s);
7247 : :
7248 : : // Using our own utrace-based uprobes
7249 : : void emit_module_utrace_decls (systemtap_session& s);
7250 : : void emit_module_utrace_init (systemtap_session& s);
7251 : : void emit_module_utrace_exit (systemtap_session& s);
7252 : :
7253 : : // Using the upstream inode-based uprobes
7254 : : void emit_module_inode_decls (systemtap_session& s);
7255 : : void emit_module_inode_init (systemtap_session& s);
7256 : : void emit_module_inode_exit (systemtap_session& s);
7257 : :
7258 : : // Using the dyninst backend (via stapdyn)
7259 : : void emit_module_dyninst_decls (systemtap_session& s);
7260 : : void emit_module_dyninst_init (systemtap_session& s);
7261 : : void emit_module_dyninst_exit (systemtap_session& s);
7262 : :
7263 : : public:
7264 : : void emit_module_decls (systemtap_session& s);
7265 : : void emit_module_init (systemtap_session& s);
7266 : : void emit_module_exit (systemtap_session& s);
7267 : : };
7268 : :
7269 : :
7270 : : void
7271 : 11861 : uprobe_derived_probe::join_group (systemtap_session& s)
7272 : : {
7273 [ + + ]: 11861 : if (! s.uprobe_derived_probes)
7274 [ + - ]: 27 : s.uprobe_derived_probes = new uprobe_derived_probe_group ();
7275 : 11861 : s.uprobe_derived_probes->enroll (this);
7276 [ - + ]: 11861 : if (s.runtime_usermode_p())
7277 : 0 : enable_dynprobes(s);
7278 : : else
7279 : 11861 : enable_task_finder(s);
7280 : :
7281 : : // Ask buildrun.cxx to build extra module if needed, and
7282 : : // signal staprun to load that module. If we're using the builtin
7283 : : // inode-uprobes, we still need to know that it is required.
7284 : 11861 : s.need_uprobes = true;
7285 : 11861 : }
7286 : :
7287 : :
7288 : : void
7289 : 11819 : uprobe_derived_probe::getargs(std::list<std::string> &arg_set) const
7290 : : {
7291 : 11819 : dwarf_derived_probe::getargs(arg_set);
7292 : 11819 : arg_set.insert(arg_set.end(), args.begin(), args.end());
7293 : 11819 : }
7294 : :
7295 : :
7296 : : void
7297 : 48 : uprobe_derived_probe::saveargs(int nargs)
7298 : : {
7299 [ + + ]: 106 : for (int i = 1; i <= nargs; i++)
7300 [ + - ][ + - ]: 58 : args.push_back("$arg" + lex_cast (i) + ":long");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
7301 : 48 : }
7302 : :
7303 : :
7304 : : void
7305 : 6 : uprobe_derived_probe::emit_privilege_assertion (translator_output* o)
7306 : : {
7307 : : // These probes are allowed for unprivileged users, but only in the
7308 : : // context of processes which they own.
7309 : 6 : emit_process_owner_assertion (o);
7310 : 6 : }
7311 : :
7312 : :
7313 [ # # ]: 0 : struct uprobe_builder: public derived_probe_builder
7314 : : {
7315 : 2436 : uprobe_builder() {}
7316 : 1 : virtual void build(systemtap_session & sess,
7317 : : probe * base,
7318 : : probe_point * location,
7319 : : literal_map_t const & parameters,
7320 : : vector<derived_probe *> & finished_results)
7321 : : {
7322 : : int64_t process, address;
7323 : :
7324 [ + - ][ - + ]: 1 : if (kernel_supports_inode_uprobes(sess))
7325 [ # # ][ # # ]: 0 : throw semantic_error (_("absolute process probes not available [man error::inode-uprobes]"));
7326 : :
7327 [ + - ]: 1 : bool b1 = get_param (parameters, TOK_PROCESS, process);
7328 : : (void) b1;
7329 [ + - ]: 1 : bool b2 = get_param (parameters, TOK_STATEMENT, address);
7330 : : (void) b2;
7331 [ + - ]: 1 : bool rr = has_null_param (parameters, TOK_RETURN);
7332 [ + - ][ - + ]: 1 : assert (b1 && b2); // by pattern_root construction
7333 : :
7334 [ + - ][ + - ]: 1 : finished_results.push_back(new uprobe_derived_probe(base, location, process, address, rr));
[ + - ]
7335 : 1 : }
7336 : : };
7337 : :
7338 : :
7339 : : void
7340 : 6 : uprobe_derived_probe_group::emit_module_maxuprobes (systemtap_session& s)
7341 : : {
7342 : : // We'll probably need at least this many:
7343 : 6 : unsigned minuprobes = probes.size();
7344 : : // .. but we don't want so many that .bss is inflated (PR10507):
7345 : 6 : unsigned uprobesize = 64;
7346 : 6 : unsigned maxuprobesmem = 10*1024*1024; // 10 MB
7347 : 6 : unsigned maxuprobes = maxuprobesmem / uprobesize;
7348 : :
7349 : : // Let's choose a value on the geometric middle. This should end up
7350 : : // between minuprobes and maxuprobes. It's OK if this number turns
7351 : : // out to be < minuprobes or > maxuprobes. At worst, we get a
7352 : : // run-time error of one kind (too few: missed uprobe registrations)
7353 : : // or another (too many: vmalloc errors at module load time).
7354 : 6 : unsigned default_maxuprobes = (unsigned)sqrt((double)minuprobes * (double)maxuprobes);
7355 : :
7356 : 6 : s.op->newline() << "#ifndef MAXUPROBES";
7357 : 6 : s.op->newline() << "#define MAXUPROBES " << default_maxuprobes;
7358 : 6 : s.op->newline() << "#endif";
7359 : 6 : }
7360 : :
7361 : :
7362 : : void
7363 : 6 : uprobe_derived_probe_group::emit_module_utrace_decls (systemtap_session& s)
7364 : : {
7365 [ + - ][ + - ]: 12 : if (probes.empty()) return;
7366 [ + - ][ + - ]: 6 : s.op->newline() << "/* ---- utrace uprobes ---- */";
7367 : : // If uprobes isn't in the kernel, pull it in from the runtime.
7368 : :
7369 [ + - ][ + - ]: 6 : s.op->newline() << "#if defined(CONFIG_UPROBES) || defined(CONFIG_UPROBES_MODULE)";
7370 [ + - ][ + - ]: 6 : s.op->newline() << "#include <linux/uprobes.h>";
7371 [ + - ][ + - ]: 6 : s.op->newline() << "#else";
7372 [ + - ][ + - ]: 6 : s.op->newline() << "#include \"linux/uprobes/uprobes.h\"";
7373 [ + - ][ + - ]: 6 : s.op->newline() << "#endif";
7374 [ + - ][ + - ]: 6 : s.op->newline() << "#ifndef UPROBES_API_VERSION";
7375 [ + - ][ + - ]: 6 : s.op->newline() << "#define UPROBES_API_VERSION 1";
7376 [ + - ][ + - ]: 6 : s.op->newline() << "#endif";
7377 : :
7378 [ + - ]: 6 : emit_module_maxuprobes (s);
7379 : :
7380 : : // Forward decls
7381 [ + - ][ + - ]: 6 : s.op->newline() << "#include \"linux/uprobes-common.h\"";
7382 : :
7383 : : // In .bss, the shared pool of uprobe/uretprobe structs. These are
7384 : : // too big to embed in the initialized .data stap_uprobe_spec array.
7385 : : // XXX: consider a slab cache or somesuch for stap_uprobes
7386 [ + - ][ + - ]: 6 : s.op->newline() << "static struct stap_uprobe stap_uprobes [MAXUPROBES];";
7387 [ + - ][ + - ]: 6 : s.op->newline() << "static DEFINE_MUTEX(stap_uprobes_lock);"; // protects against concurrent registration/unregistration
7388 : :
7389 [ + - ]: 6 : s.op->assert_0_indent();
7390 : :
7391 : : // Assign task-finder numbers as we build up the stap_uprobe_tf table.
7392 : : // This means we process probes[] in two passes.
7393 [ + - ]: 6 : map <string,unsigned> module_index;
7394 : 6 : unsigned module_index_ctr = 0;
7395 : :
7396 : : // not const since embedded task_finder_target struct changes
7397 [ + - ][ + - ]: 6 : s.op->newline() << "static struct stap_uprobe_tf stap_uprobe_finders[] = {";
7398 [ + - ]: 6 : s.op->indent(1);
7399 [ + + ]: 12 : for (unsigned i=0; i<probes.size(); i++)
7400 : : {
7401 : 6 : uprobe_derived_probe *p = probes[i];
7402 [ + - ]: 6 : string pbmkey = make_pbm_key (p);
7403 [ + - ][ + - ]: 6 : if (module_index.find (pbmkey) == module_index.end())
[ + - ]
7404 : : {
7405 [ + - ]: 6 : module_index[pbmkey] = module_index_ctr++;
7406 : :
7407 [ + - ][ + - ]: 6 : s.op->newline() << "{";
7408 : : // NB: it's essential that make_pbm_key() use all of and
7409 : : // only the same fields as we're about to emit.
7410 [ + - ][ + - ]: 6 : s.op->line() << " .finder={";
7411 [ + - ][ + - ]: 6 : s.op->line() << " .purpose=\"uprobes\",";
7412 [ - + ]: 6 : if (p->pid != 0)
7413 [ # # ][ # # ]: 0 : s.op->line() << " .pid=" << p->pid << ",";
[ # # ][ # # ]
7414 : :
7415 [ + - ][ + + ]: 6 : if (p->section == "") // .statement(addr).absolute
7416 [ + - ][ + - ]: 1 : s.op->line() << " .callback=&stap_uprobe_process_found,";
7417 [ + - ][ + - ]: 5 : else if (p->section == ".absolute") // proxy for ET_EXEC -> exec()'d program
7418 : : {
7419 [ + - ][ + - ]: 5 : s.op->line() << " .procname=" << lex_cast_qstring(p->module) << ",";
[ + - ][ + - ]
[ + - ][ + - ]
7420 [ + - ][ + - ]: 5 : s.op->line() << " .callback=&stap_uprobe_process_found,";
7421 : : }
7422 [ # # ][ # # ]: 0 : else if (p->section != ".absolute") // ET_DYN
7423 : : {
7424 [ # # ]: 0 : if (p->has_library)
7425 [ # # ][ # # ]: 0 : s.op->line() << " .procname=\"" << p->path << "\", ";
[ # # ][ # # ]
7426 [ # # ][ # # ]: 0 : s.op->line() << " .mmap_callback=&stap_uprobe_mmap_found, ";
7427 [ # # ][ # # ]: 0 : s.op->line() << " .munmap_callback=&stap_uprobe_munmap_found, ";
7428 [ # # ][ # # ]: 0 : s.op->line() << " .callback=&stap_uprobe_process_munmap,";
7429 : : }
7430 [ + - ][ + - ]: 6 : s.op->line() << " },";
7431 [ + - ][ + + ]: 6 : if (p->module != "")
7432 [ + - ][ + - ]: 5 : s.op->line() << " .pathname=" << lex_cast_qstring(p->module) << ", ";
[ + - ][ + - ]
[ + - ][ + - ]
7433 [ + - ][ + - ]: 6 : s.op->line() << " },";
7434 : : }
7435 : : else
7436 : : { } // skip it in this pass, already have a suitable stap_uprobe_tf slot for it.
7437 [ + - ]: 6 : }
7438 [ + - ][ + - ]: 6 : s.op->newline(-1) << "};";
7439 : :
7440 [ + - ]: 6 : s.op->assert_0_indent();
7441 : :
7442 : : unsigned pci;
7443 [ + + ]: 12 : for (pci=0; pci<probes.size(); pci++)
7444 : : {
7445 : : // List of perf counters used by each probe
7446 : : // This list is an index into struct stap_perf_probe,
7447 : 6 : uprobe_derived_probe *p = probes[pci];
7448 : 6 : std::set<derived_probe*>::iterator pcii;
7449 [ + - ][ + - ]: 6 : s.op->newline() << "long perf_counters_" + lex_cast(pci) + "[] = {";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
7450 [ + - ][ + + ]: 14 : for (pcii = p->perf_counter_refs.begin();
7451 [ + - ]: 7 : pcii != p->perf_counter_refs.end(); pcii++)
7452 : : {
7453 : 1 : map<string, pair<string,derived_probe*> >::iterator it;
7454 : 1 : unsigned i = 0;
7455 : : // Find the associated perf.counter probe
7456 [ + - ][ + - ]: 2 : for (it=s.perf_counters.begin() ;
7457 [ + - ]: 1 : it != s.perf_counters.end(); it++, i++)
7458 [ + - ]: 1 : if ((*it).second.second == (*pcii))
7459 : 1 : break;
7460 [ + - ][ + - ]: 1 : s.op->line() << lex_cast(i) << ", ";
[ + - ][ + - ]
[ + - ]
7461 : : }
7462 [ + - ][ + - ]: 6 : s.op->newline() << "};";
7463 : : }
7464 : :
7465 : : // NB: read-only structure
7466 [ + - ][ + - ]: 6 : s.op->newline() << "static const struct stap_uprobe_spec stap_uprobe_specs [] = {";
7467 [ + - ]: 6 : s.op->indent(1);
7468 [ + + ]: 12 : for (unsigned i =0; i<probes.size(); i++)
7469 : : {
7470 : 6 : uprobe_derived_probe* p = probes[i];
7471 [ + - ][ + - ]: 6 : s.op->newline() << "{";
7472 [ + - ]: 6 : string key = make_pbm_key (p);
7473 [ + - ]: 6 : unsigned value = module_index[key];
7474 [ - + ]: 6 : if (value != 0)
7475 [ # # ][ # # ]: 0 : s.op->line() << " .tfi=" << value << ",";
[ # # ][ # # ]
7476 [ + - ][ + - ]: 6 : s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
[ + - ][ + - ]
[ + - ][ + - ]
7477 [ + - ][ + - ]: 6 : s.op->line() << " .probe=" << common_probe_init (p) << ",";
[ + - ][ + - ]
[ + - ][ + - ]
7478 : :
7479 [ - + ]: 6 : if (p->sdt_semaphore_addr != 0)
7480 [ # # ][ # # ]: 0 : s.op->line() << " .sdt_sem_offset=(unsigned long)0x"
7481 [ # # ][ # # ]: 0 : << hex << p->sdt_semaphore_addr << dec << "ULL,";
[ # # ][ # # ]
7482 : :
7483 : : // XXX: don't bother emit if array is empty
7484 [ + - ][ + - ]: 6 : s.op->line() << " .perf_counters_dim=ARRAY_SIZE(perf_counters_" << lex_cast(i) << "),";
[ + - ][ + - ]
[ + - ][ + - ]
7485 : : // List of perf counters used by a probe from above
7486 [ + - ][ + - ]: 6 : s.op->line() << " .perf_counters=perf_counters_" + lex_cast(i) + ",";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
7487 : :
7488 [ - + ]: 6 : if (p->has_return)
7489 [ # # ][ # # ]: 0 : s.op->line() << " .return_p=1,";
7490 [ + - ][ + - ]: 6 : s.op->line() << " },";
7491 [ + - ]: 6 : }
7492 [ + - ][ + - ]: 6 : s.op->newline(-1) << "};";
7493 : :
7494 [ + - ]: 6 : s.op->assert_0_indent();
7495 : :
7496 [ + - ][ + - ]: 6 : s.op->newline() << "static void enter_uprobe_probe (struct uprobe *inst, struct pt_regs *regs) {";
7497 [ + - ][ + - ]: 6 : s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);";
7498 [ + - ][ + - ]: 6 : s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
7499 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sups->probe",
7500 [ + - ][ + - ]: 6 : "stp_probe_type_uprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
7501 [ + - ][ + - ]: 6 : s.op->newline() << "if (sup->spec_index < 0 || "
7502 [ + - ][ + - ]: 6 : << "sup->spec_index >= " << probes.size() << ") {";
[ + - ]
7503 [ + - ][ + - ]: 6 : s.op->newline(1) << "_stp_error (\"bad spec_index %d (max " << probes.size()
[ + - ]
7504 [ + - ]: 6 : << "): %s\", sup->spec_index, c->probe_point);";
7505 [ + - ][ + - ]: 6 : s.op->newline() << "atomic_dec (&c->busy);";
7506 [ + - ][ + - ]: 6 : s.op->newline() << "goto probe_epilogue;";
7507 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7508 [ + - ][ + - ]: 6 : s.op->newline() << "c->uregs = regs;";
7509 [ + - ][ + - ]: 6 : s.op->newline() << "c->user_mode_p = 1;";
7510 : :
7511 : : // Make it look like the IP is set as it would in the actual user
7512 : : // task when calling real probe handler. Reset IP regs on return, so
7513 : : // we don't confuse uprobes. PR10458
7514 [ + - ][ + - ]: 6 : s.op->newline() << "{";
7515 [ + - ]: 6 : s.op->indent(1);
7516 [ + - ][ + - ]: 6 : s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->uregs);";
7517 [ + - ][ + - ]: 6 : s.op->newline() << "SET_REG_IP(regs, inst->vaddr);";
7518 [ + - ][ + - ]: 6 : s.op->newline() << "(*sups->probe->ph) (c);";
7519 [ + - ][ + - ]: 6 : s.op->newline() << "SET_REG_IP(regs, uprobes_ip);";
7520 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7521 : :
7522 [ + - ]: 6 : common_probe_entryfn_epilogue (s, true);
7523 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7524 : :
7525 [ + - ][ + - ]: 6 : s.op->newline() << "static void enter_uretprobe_probe (struct uretprobe_instance *inst, struct pt_regs *regs) {";
7526 [ + - ][ + - ]: 6 : s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);";
7527 [ + - ][ + - ]: 6 : s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
7528 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sups->probe",
7529 [ + - ][ + - ]: 6 : "stp_probe_type_uretprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
7530 [ + - ][ + - ]: 6 : s.op->newline() << "c->ips.ri = inst;";
7531 [ + - ][ + - ]: 6 : s.op->newline() << "if (sup->spec_index < 0 || "
7532 [ + - ][ + - ]: 6 : << "sup->spec_index >= " << probes.size() << ") {";
[ + - ]
7533 [ + - ][ + - ]: 6 : s.op->newline(1) << "_stp_error (\"bad spec_index %d (max " << probes.size()
[ + - ]
7534 [ + - ]: 6 : << "): %s\", sup->spec_index, c->probe_point);";
7535 [ + - ][ + - ]: 6 : s.op->newline() << "atomic_dec (&c->busy);";
7536 [ + - ][ + - ]: 6 : s.op->newline() << "goto probe_epilogue;";
7537 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7538 : :
7539 [ + - ][ + - ]: 6 : s.op->newline() << "c->uregs = regs;";
7540 [ + - ][ + - ]: 6 : s.op->newline() << "c->user_mode_p = 1;";
7541 : :
7542 : : // Make it look like the IP is set as it would in the actual user
7543 : : // task when calling real probe handler. Reset IP regs on return, so
7544 : : // we don't confuse uprobes. PR10458
7545 [ + - ][ + - ]: 6 : s.op->newline() << "{";
7546 [ + - ]: 6 : s.op->indent(1);
7547 [ + - ][ + - ]: 6 : s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->uregs);";
7548 [ + - ][ + - ]: 6 : s.op->newline() << "SET_REG_IP(regs, inst->ret_addr);";
7549 [ + - ][ + - ]: 6 : s.op->newline() << "(*sups->probe->ph) (c);";
7550 [ + - ][ + - ]: 6 : s.op->newline() << "SET_REG_IP(regs, uprobes_ip);";
7551 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7552 : :
7553 [ + - ]: 6 : common_probe_entryfn_epilogue (s, true);
7554 [ + - ][ + - ]: 6 : s.op->newline(-1) << "}";
7555 : :
7556 [ + - ]: 6 : s.op->newline();
7557 [ + - ][ + - ]: 6 : s.op->newline() << "#include \"linux/uprobes-common.c\"";
7558 [ + - ][ + - ]: 6 : s.op->newline();
7559 : : }
7560 : :
7561 : :
7562 : : void
7563 : 6 : uprobe_derived_probe_group::emit_module_utrace_init (systemtap_session& s)
7564 : : {
7565 [ - + ]: 12 : if (probes.empty()) return;
7566 : :
7567 : 6 : s.op->newline() << "/* ---- utrace uprobes ---- */";
7568 : :
7569 : 6 : s.op->newline() << "for (j=0; j<MAXUPROBES; j++) {";
7570 : 6 : s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[j];";
7571 : 6 : s.op->newline() << "sup->spec_index = -1;"; // free slot
7572 : : // NB: we assume the rest of the struct (specificaly, sup->up) is
7573 : : // initialized to zero. This is so that we can use
7574 : : // sup->up->kdata = NULL for "really free!" PR 6829.
7575 : 6 : s.op->newline(-1) << "}";
7576 : 6 : s.op->newline() << "mutex_init (& stap_uprobes_lock);";
7577 : :
7578 : : // Set up the task_finders
7579 : 6 : s.op->newline() << "for (i=0; i<sizeof(stap_uprobe_finders)/sizeof(stap_uprobe_finders[0]); i++) {";
7580 : 6 : s.op->newline(1) << "struct stap_uprobe_tf *stf = & stap_uprobe_finders[i];";
7581 : 6 : s.op->newline() << "probe_point = stf->pathname;"; // for error messages; XXX: would prefer pp() or something better
7582 : 6 : s.op->newline() << "rc = stap_register_task_finder_target (& stf->finder);";
7583 : :
7584 : : // NB: if (rc), there is no need (XXX: nor any way) to clean up any
7585 : : // finders already registered, since mere registration does not
7586 : : // cause any utrace or memory allocation actions. That happens only
7587 : : // later, once the task finder engine starts running. So, for a
7588 : : // partial initialization requiring unwind, we need do nothing.
7589 : 6 : s.op->newline() << "if (rc) break;";
7590 : :
7591 : 6 : s.op->newline(-1) << "}";
7592 : : }
7593 : :
7594 : :
7595 : : void
7596 : 13 : uprobe_derived_probe_group::emit_module_utrace_exit (systemtap_session& s)
7597 : : {
7598 [ - + ]: 26 : if (probes.empty()) return;
7599 : 13 : s.op->newline() << "/* ---- utrace uprobes ---- */";
7600 : :
7601 : : // NB: there is no stap_unregister_task_finder_target call;
7602 : : // important stuff like utrace cleanups are done by
7603 : : // __stp_task_finder_cleanup() via stap_stop_task_finder().
7604 : : //
7605 : : // This function blocks until all callbacks are completed, so there
7606 : : // is supposed to be no possibility of any registration-related code starting
7607 : : // to run in parallel with our shutdown here. So we don't need to protect the
7608 : : // stap_uprobes[] array with the mutex.
7609 : :
7610 : 13 : s.op->newline() << "for (j=0; j<MAXUPROBES; j++) {";
7611 : 13 : s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[j];";
7612 : 13 : s.op->newline() << "const struct stap_uprobe_spec *sups = &stap_uprobe_specs [sup->spec_index];";
7613 : 13 : s.op->newline() << "if (sup->spec_index < 0) continue;"; // free slot
7614 : :
7615 : : // PR10655: decrement that ENABLED semaphore
7616 : 13 : s.op->newline() << "if (sup->sdt_sem_address) {";
7617 : 13 : s.op->newline(1) << "unsigned short sdt_semaphore;"; // NB: fixed size
7618 : 13 : s.op->newline() << "pid_t pid = (sups->return_p ? sup->urp.u.pid : sup->up.pid);";
7619 : 13 : s.op->newline() << "struct task_struct *tsk;";
7620 : 13 : s.op->newline() << "rcu_read_lock();";
7621 : :
7622 : : // Do a pid->task_struct* lookup. For 2.6.24+, this code assumes
7623 : : // that the pid is always in the global namespace, not in any
7624 : : // private namespace.
7625 : 13 : s.op->newline() << "#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)";
7626 : : // We'd like to call find_task_by_pid_ns() here, but it isn't
7627 : : // exported. So, we call what it calls...
7628 : 13 : s.op->newline() << " tsk = pid_task(find_pid_ns(pid, &init_pid_ns), PIDTYPE_PID);";
7629 : 13 : s.op->newline() << "#else";
7630 : 13 : s.op->newline() << " tsk = find_task_by_pid (pid);";
7631 : 13 : s.op->newline() << "#endif /* 2.6.24 */";
7632 : :
7633 : 13 : s.op->newline() << "if (tsk) {"; // just in case the thing exited while we weren't watching
7634 : 13 : s.op->newline(1) << "if (__access_process_vm_noflush(tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof(sdt_semaphore), 0)) {";
7635 : 13 : s.op->newline(1) << "sdt_semaphore --;";
7636 : 13 : s.op->newline() << "#ifdef DEBUG_UPROBES";
7637 : 13 : s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"-semaphore %#x @ %#lx\\n\", sdt_semaphore, sup->sdt_sem_address);";
7638 : 13 : s.op->newline() << "#endif";
7639 : 13 : s.op->newline() << "__access_process_vm_noflush(tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof(sdt_semaphore), 1);";
7640 : 13 : s.op->newline(-1) << "}";
7641 : : // XXX: need to analyze possibility of race condition
7642 : 13 : s.op->newline(-1) << "}";
7643 : 13 : s.op->newline() << "rcu_read_unlock();";
7644 : 13 : s.op->newline(-1) << "}";
7645 : :
7646 : 13 : s.op->newline() << "if (sups->return_p) {";
7647 : 13 : s.op->newline(1) << "#ifdef DEBUG_UPROBES";
7648 : 13 : 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);";
7649 : 13 : s.op->newline() << "#endif";
7650 : : // NB: PR6829 does not change that we still need to unregister at
7651 : : // *this* time -- when the script as a whole exits.
7652 : 13 : s.op->newline() << "unregister_uretprobe (& sup->urp);";
7653 : 13 : s.op->newline(-1) << "} else {";
7654 : 13 : s.op->newline(1) << "#ifdef DEBUG_UPROBES";
7655 : 13 : 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);";
7656 : 13 : s.op->newline() << "#endif";
7657 : 13 : s.op->newline() << "unregister_uprobe (& sup->up);";
7658 : 13 : s.op->newline(-1) << "}";
7659 : :
7660 : 13 : s.op->newline() << "sup->spec_index = -1;";
7661 : :
7662 : : // XXX: uprobe missed counts?
7663 : :
7664 : 13 : s.op->newline(-1) << "}";
7665 : :
7666 : 13 : s.op->newline() << "mutex_destroy (& stap_uprobes_lock);";
7667 : : }
7668 : :
7669 : :
7670 : : void
7671 : 0 : uprobe_derived_probe_group::emit_module_inode_decls (systemtap_session& s)
7672 : : {
7673 [ # # ][ # # ]: 0 : if (probes.empty()) return;
7674 [ # # ][ # # ]: 0 : s.op->newline() << "/* ---- inode uprobes ---- */";
7675 [ # # ]: 0 : emit_module_maxuprobes (s);
7676 [ # # ][ # # ]: 0 : s.op->newline() << "#include \"linux/uprobes-inode.c\"";
7677 : :
7678 : : // Write the probe handler.
7679 [ # # ][ # # ]: 0 : s.op->newline() << "static int stapiu_probe_handler "
7680 [ # # ]: 0 : << "(struct stapiu_consumer *sup, struct pt_regs *regs) {";
7681 [ # # ]: 0 : s.op->newline(1);
7682 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sup->probe",
7683 [ # # ][ # # ]: 0 : "stp_probe_type_uprobe");
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
7684 [ # # ][ # # ]: 0 : s.op->newline() << "c->uregs = regs;";
7685 [ # # ][ # # ]: 0 : s.op->newline() << "c->user_mode_p = 1;";
7686 : : // NB: IP is already set by stapiu_probe_prehandler in uprobes-inode.c
7687 [ # # ][ # # ]: 0 : s.op->newline() << "(*sup->probe->ph) (c);";
7688 : :
7689 [ # # ]: 0 : common_probe_entryfn_epilogue (s, true);
7690 [ # # ][ # # ]: 0 : s.op->newline() << "return 0;";
7691 [ # # ][ # # ]: 0 : s.op->newline(-1) << "}";
7692 [ # # ]: 0 : s.op->assert_0_indent();
7693 : :
7694 : : // Index of all the modules for which we need inodes.
7695 [ # # ]: 0 : map<string, unsigned> module_index;
7696 : 0 : unsigned module_index_ctr = 0;
7697 : :
7698 : : // Discover and declare targets for each unique path.
7699 [ # # ][ # # ]: 0 : s.op->newline() << "static struct stapiu_target "
7700 [ # # ]: 0 : << "stap_inode_uprobe_targets[] = {";
7701 [ # # ]: 0 : s.op->indent(1);
7702 [ # # ]: 0 : for (unsigned i=0; i<probes.size(); i++)
7703 : : {
7704 : 0 : uprobe_derived_probe *p = probes[i];
7705 [ # # ]: 0 : const string key = make_pbm_key(p);
7706 [ # # ][ # # ]: 0 : if (module_index.find (key) == module_index.end())
[ # # ]
7707 : : {
7708 [ # # ]: 0 : module_index[key] = module_index_ctr++;
7709 [ # # ][ # # ]: 0 : s.op->newline() << "{";
7710 [ # # ][ # # ]: 0 : s.op->line() << " .finder={";
7711 [ # # ][ # # ]: 0 : s.op->line() << " .purpose=\"inode-uprobes\",";
7712 [ # # ]: 0 : if (p->pid != 0)
7713 [ # # ][ # # ]: 0 : s.op->line() << " .pid=" << p->pid << ",";
[ # # ][ # # ]
7714 : :
7715 [ # # ][ # # ]: 0 : if (p->section == "") // .statement(addr).absolute XXX?
7716 [ # # ][ # # ]: 0 : s.op->line() << " .callback=&stapiu_process_found,";
7717 [ # # ][ # # ]: 0 : else if (p->section == ".absolute") // proxy for ET_EXEC -> exec()'d program
7718 : : {
7719 [ # # ][ # # ]: 0 : s.op->line() << " .procname=" << lex_cast_qstring(p->module) << ",";
[ # # ][ # # ]
[ # # ][ # # ]
7720 [ # # ][ # # ]: 0 : s.op->line() << " .callback=&stapiu_process_found,";
7721 : : }
7722 [ # # ][ # # ]: 0 : else if (p->section != ".absolute") // ET_DYN
7723 : : {
7724 [ # # ]: 0 : if (p->has_library)
7725 [ # # ][ # # ]: 0 : s.op->line() << " .procname=\"" << p->path << "\", ";
[ # # ][ # # ]
7726 [ # # ][ # # ]: 0 : s.op->line() << " .mmap_callback=&stapiu_mmap_found, ";
7727 [ # # ][ # # ]: 0 : s.op->line() << " .munmap_callback=&stapiu_munmap_found, ";
7728 [ # # ][ # # ]: 0 : s.op->line() << " .callback=&stapiu_process_munmap,";
7729 : : }
7730 [ # # ][ # # ]: 0 : s.op->line() << " },";
7731 [ # # ][ # # ]: 0 : s.op->line() << " .filename=" << lex_cast_qstring(p->module) << ",";
[ # # ][ # # ]
[ # # ][ # # ]
7732 [ # # ][ # # ]: 0 : s.op->line() << " },";
7733 : : }
7734 [ # # ]: 0 : }
7735 [ # # ][ # # ]: 0 : s.op->newline(-1) << "};";
7736 [ # # ]: 0 : s.op->assert_0_indent();
7737 : :
7738 : : // Declare the actual probes.
7739 : : unsigned pci;
7740 [ # # ]: 0 : for (pci=0; pci<probes.size(); pci++)
7741 : : {
7742 : : // List of perf counters used by each probe
7743 : : // This list is an index into struct stap_perf_probe,
7744 : 0 : uprobe_derived_probe *p = probes[pci];
7745 : 0 : std::set<derived_probe*>::iterator pcii;
7746 [ # # ][ # # ]: 0 : s.op->newline() << "long perf_counters_" + lex_cast(pci) + "[] = {";
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
7747 [ # # ][ # # ]: 0 : for (pcii = p->perf_counter_refs.begin();
7748 [ # # ]: 0 : pcii != p->perf_counter_refs.end(); pcii++)
7749 : : {
7750 : 0 : map<string, pair<string,derived_probe*> >::iterator it;
7751 : 0 : unsigned i = 0;
7752 : : // Find the associated perf.counter probe
7753 [ # # ][ # # ]: 0 : for (it=s.perf_counters.begin() ;
7754 [ # # ]: 0 : it != s.perf_counters.end(); it++, i++)
7755 [ # # ]: 0 : if ((*it).second.second == (*pcii))
7756 : 0 : break;
7757 [ # # ][ # # ]: 0 : s.op->line() << lex_cast(i) << ", ";
[ # # ][ # # ]
[ # # ]
7758 : : }
7759 [ # # ][ # # ]: 0 : s.op->newline() << "};";
7760 : : }
7761 : :
7762 [ # # ][ # # ]: 0 : s.op->newline() << "static struct stapiu_consumer "
7763 [ # # ]: 0 : << "stap_inode_uprobe_consumers[] = {";
7764 [ # # ]: 0 : s.op->indent(1);
7765 [ # # ]: 0 : for (unsigned i=0; i<probes.size(); i++)
7766 : : {
7767 : 0 : uprobe_derived_probe *p = probes[i];
7768 [ # # ][ # # ]: 0 : unsigned index = module_index[make_pbm_key(p)];
[ # # ]
7769 [ # # ][ # # ]: 0 : s.op->newline() << "{";
7770 [ # # ]: 0 : if (p->has_return)
7771 [ # # ][ # # ]: 0 : s.op->line() << " .return_p=1,";
7772 [ # # ][ # # ]: 0 : s.op->line() << " .target=&stap_inode_uprobe_targets[" << index << "],";
[ # # ][ # # ]
7773 [ # # ][ # # ]: 0 : s.op->line() << " .offset=(loff_t)0x" << hex << p->addr << dec << "ULL,";
[ # # ][ # # ]
[ # # ][ # # ]
7774 [ # # ]: 0 : if (p->sdt_semaphore_addr)
7775 [ # # ][ # # ]: 0 : s.op->line() << " .sdt_sem_offset=(loff_t)0x"
7776 [ # # ][ # # ]: 0 : << hex << p->sdt_semaphore_addr << dec << "ULL,";
[ # # ][ # # ]
7777 : : // XXX: don't bother emit if array is empty
7778 [ # # ][ # # ]: 0 : s.op->line() << " .perf_counters_dim=ARRAY_SIZE(perf_counters_" << lex_cast(i) << "),";
[ # # ][ # # ]
[ # # ][ # # ]
7779 : : // List of perf counters used by a probe from above
7780 [ # # ][ # # ]: 0 : s.op->line() << " .perf_counters=perf_counters_" + lex_cast(i) + ",";
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
7781 [ # # ][ # # ]: 0 : s.op->line() << " .probe=" << common_probe_init (p) << ",";
[ # # ][ # # ]
[ # # ][ # # ]
7782 [ # # ][ # # ]: 0 : s.op->line() << " },";
7783 : : }
7784 [ # # ][ # # ]: 0 : s.op->newline(-1) << "};";
7785 [ # # ][ # # ]: 0 : s.op->assert_0_indent();
7786 : : }
7787 : :
7788 : :
7789 : : void
7790 : 0 : uprobe_derived_probe_group::emit_module_inode_init (systemtap_session& s)
7791 : : {
7792 [ # # ]: 0 : if (probes.empty()) return;
7793 : 0 : s.op->newline() << "/* ---- inode uprobes ---- */";
7794 : : // Let stapiu_init() handle reporting errors by setting probe_point
7795 : : // to NULL.
7796 : 0 : s.op->newline() << "probe_point = NULL;";
7797 : 0 : s.op->newline() << "rc = stapiu_init ("
7798 : 0 : << "stap_inode_uprobe_targets, "
7799 : 0 : << "ARRAY_SIZE(stap_inode_uprobe_targets), "
7800 : 0 : << "stap_inode_uprobe_consumers, "
7801 : 0 : << "ARRAY_SIZE(stap_inode_uprobe_consumers));";
7802 : : }
7803 : :
7804 : :
7805 : : void
7806 : 0 : uprobe_derived_probe_group::emit_module_inode_exit (systemtap_session& s)
7807 : : {
7808 [ # # ]: 0 : if (probes.empty()) return;
7809 : 0 : s.op->newline() << "/* ---- inode uprobes ---- */";
7810 : 0 : s.op->newline() << "stapiu_exit ("
7811 : 0 : << "stap_inode_uprobe_targets, "
7812 : 0 : << "ARRAY_SIZE(stap_inode_uprobe_targets), "
7813 : 0 : << "stap_inode_uprobe_consumers, "
7814 : 0 : << "ARRAY_SIZE(stap_inode_uprobe_consumers));";
7815 : : }
7816 : :
7817 : :
7818 : : void
7819 : 0 : uprobe_derived_probe_group::emit_module_dyninst_decls (systemtap_session& s)
7820 : : {
7821 [ # # ]: 0 : if (probes.empty()) return;
7822 : 0 : s.op->newline() << "/* ---- dyninst uprobes ---- */";
7823 : 0 : emit_module_maxuprobes (s);
7824 : 0 : s.op->newline() << "#include \"dyninst/uprobes.h\"";
7825 : :
7826 : : // Let the dynprobe_derived_probe_group handle outputting targets
7827 : : // and probes. This allows us to merge different types of probes.
7828 : 0 : s.op->newline() << "static struct stapdu_probe stapdu_probes[];";
7829 [ # # ]: 0 : for (unsigned i = 0; i < probes.size(); i++)
7830 : : {
7831 : 0 : uprobe_derived_probe *p = probes[i];
7832 : :
7833 : : dynprobe_add_uprobe(s, p->module, p->addr, p->sdt_semaphore_addr,
7834 : : (p->has_return ? "STAPDYN_PROBE_FLAG_RETURN" : "0"),
7835 [ # # ][ # # ]: 0 : common_probe_init(p));
[ # # ][ # # ]
[ # # ][ # # ]
7836 : : }
7837 : : // loc2c-generated code assumes pt_regs are available, so use this to make
7838 : : // sure we always have *something* for it to dereference...
7839 : 0 : s.op->newline() << "static struct pt_regs stapdu_dummy_uregs;";
7840 : :
7841 : : // Write the probe handler.
7842 : : // NB: not static, so dyninst can find it
7843 : 0 : s.op->newline() << "int enter_dyninst_uprobe "
7844 : 0 : << "(uint64_t index, struct pt_regs *regs) {";
7845 : 0 : s.op->newline(1) << "struct stapdu_probe *sup = &stapdu_probes[index];";
7846 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sup->probe",
7847 [ # # ][ # # ]: 0 : "stp_probe_type_uprobe");
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
7848 : 0 : s.op->newline() << "c->uregs = regs ?: &stapdu_dummy_uregs;";
7849 : 0 : s.op->newline() << "c->user_mode_p = 1;";
7850 : : // XXX: once we have regs, check how dyninst sets the IP
7851 : : // XXX: the way that dyninst rewrites stuff is probably going to be
7852 : : // ... very confusing to our backtracer (at least if we stay in process)
7853 : 0 : s.op->newline() << "(*sup->probe->ph) (c);";
7854 : 0 : common_probe_entryfn_epilogue (s, true);
7855 : 0 : s.op->newline() << "return 0;";
7856 : 0 : s.op->newline(-1) << "}";
7857 : 0 : s.op->assert_0_indent();
7858 : : }
7859 : :
7860 : :
7861 : : void
7862 : 0 : uprobe_derived_probe_group::emit_module_dyninst_init (systemtap_session& s)
7863 : : {
7864 [ # # ]: 0 : if (probes.empty()) return;
7865 : :
7866 : : /* stapdyn handles the dirty work via dyninst */
7867 : 0 : s.op->newline() << "/* ---- dyninst uprobes ---- */";
7868 : 0 : s.op->newline() << "/* this section left intentionally blank */";
7869 : : }
7870 : :
7871 : :
7872 : : void
7873 : 0 : uprobe_derived_probe_group::emit_module_dyninst_exit (systemtap_session& s)
7874 : : {
7875 [ # # ]: 0 : if (probes.empty()) return;
7876 : :
7877 : : /* stapdyn handles the dirty work via dyninst */
7878 : 0 : s.op->newline() << "/* ---- dyninst uprobes ---- */";
7879 : 0 : s.op->newline() << "/* this section left intentionally blank */";
7880 : : }
7881 : :
7882 : :
7883 : : void
7884 : 6 : uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
7885 : : {
7886 [ - + ]: 6 : if (s.runtime_usermode_p())
7887 : 0 : emit_module_dyninst_decls (s);
7888 [ - + ]: 6 : else if (kernel_supports_inode_uprobes (s))
7889 : 0 : emit_module_inode_decls (s);
7890 : : else
7891 : 6 : emit_module_utrace_decls (s);
7892 : 6 : }
7893 : :
7894 : :
7895 : : void
7896 : 6 : uprobe_derived_probe_group::emit_module_init (systemtap_session& s)
7897 : : {
7898 [ - + ]: 6 : if (s.runtime_usermode_p())
7899 : 0 : emit_module_dyninst_init (s);
7900 [ - + ]: 6 : else if (kernel_supports_inode_uprobes (s))
7901 : 0 : emit_module_inode_init (s);
7902 : : else
7903 : 6 : emit_module_utrace_init (s);
7904 : 6 : }
7905 : :
7906 : :
7907 : : void
7908 : 13 : uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
7909 : : {
7910 [ - + ]: 13 : if (s.runtime_usermode_p())
7911 : 0 : emit_module_dyninst_exit (s);
7912 [ - + ]: 13 : else if (kernel_supports_inode_uprobes (s))
7913 : 0 : emit_module_inode_exit (s);
7914 : : else
7915 : 13 : emit_module_utrace_exit (s);
7916 : 13 : }
7917 : :
7918 : :
7919 : : // ------------------------------------------------------------------------
7920 : : // Kprobe derived probes
7921 : : // ------------------------------------------------------------------------
7922 : :
7923 [ + - ]: 2414 : static const string TOK_KPROBE("kprobe");
7924 : :
7925 [ # # ][ # # ]: 0 : struct kprobe_derived_probe: public derived_probe
[ # # ][ # # ]
7926 : : {
7927 : : kprobe_derived_probe (systemtap_session& sess,
7928 : : vector<derived_probe *> & results,
7929 : : probe *base,
7930 : : probe_point *location,
7931 : : const string& name,
7932 : : int64_t stmt_addr,
7933 : : bool has_return,
7934 : : bool has_statement,
7935 : : bool has_maxactive,
7936 : : bool has_path,
7937 : : bool has_library,
7938 : : long maxactive_val,
7939 : : const string& path,
7940 : : const string& library
7941 : : );
7942 : : string symbol_name;
7943 : : Dwarf_Addr addr;
7944 : : bool has_return;
7945 : : bool has_statement;
7946 : : bool has_maxactive;
7947 : : bool has_path;
7948 : : bool has_library;
7949 : : long maxactive_val;
7950 : : string path;
7951 : : string library;
7952 : : bool access_var;
7953 : : void printsig (std::ostream &o) const;
7954 : : void join_group (systemtap_session& s);
7955 : : };
7956 : :
7957 [ # # ][ # # ]: 52 : struct kprobe_derived_probe_group: public derived_probe_group
[ + - ]
7958 : : {
7959 : : private:
7960 : : multimap<string,kprobe_derived_probe*> probes_by_module;
7961 : : typedef multimap<string,kprobe_derived_probe*>::iterator p_b_m_iterator;
7962 : :
7963 : : public:
7964 : : void enroll (kprobe_derived_probe* probe);
7965 : : void emit_module_decls (systemtap_session& s);
7966 : : void emit_module_init (systemtap_session& s);
7967 : : void emit_module_exit (systemtap_session& s);
7968 : : };
7969 : :
7970 [ - + ]: 21299 : struct kprobe_var_expanding_visitor: public var_expanding_visitor
7971 : : {
7972 : : systemtap_session& sess;
7973 : : block *add_block;
7974 : : block *add_call_probe; // synthesized from .return probes with saved $vars
7975 : : bool add_block_tid, add_call_probe_tid;
7976 : : bool has_return;
7977 : :
7978 : 21299 : kprobe_var_expanding_visitor(systemtap_session& sess, bool has_return):
7979 : : sess(sess), add_block(NULL), add_call_probe(NULL),
7980 : : add_block_tid(false), add_call_probe_tid(false),
7981 : 21299 : has_return(has_return) {}
7982 : :
7983 : : void visit_entry_op (entry_op* e);
7984 : : };
7985 : :
7986 : :
7987 : 21299 : kprobe_derived_probe::kprobe_derived_probe (systemtap_session& sess,
7988 : : vector<derived_probe *> & results,
7989 : : probe *base,
7990 : : probe_point *location,
7991 : : const string& name,
7992 : : int64_t stmt_addr,
7993 : : bool has_return,
7994 : : bool has_statement,
7995 : : bool has_maxactive,
7996 : : bool has_path,
7997 : : bool has_library,
7998 : : long maxactive_val,
7999 : : const string& path,
8000 : : const string& library
8001 : : ):
8002 : : derived_probe (base, location, true /* .components soon rewritten */ ),
8003 : : symbol_name (name), addr (stmt_addr),
8004 : : has_return (has_return), has_statement (has_statement),
8005 : : has_maxactive (has_maxactive), has_path (has_path),
8006 : : has_library (has_library),
8007 : : maxactive_val (maxactive_val),
8008 [ + - ][ + - ]: 21299 : path (path), library (library)
[ + - ]
8009 : : {
8010 : 21299 : this->tok = base->tok;
8011 : 21299 : this->access_var = false;
8012 : :
8013 : : #ifndef USHRT_MAX
8014 : : #define USHRT_MAX 32767
8015 : : #endif
8016 : :
8017 : : // Expansion of $target variables in the probe body produces an error during
8018 : : // translate phase, since we're not using debuginfo
8019 : :
8020 [ + - ]: 21299 : vector<probe_point::component*> comps;
8021 [ + - ][ + - ]: 21299 : comps.push_back (new probe_point::component(TOK_KPROBE));
[ + - ]
8022 : :
8023 [ + + ]: 21299 : if (has_statement)
8024 : : {
8025 : : comps.push_back (new probe_point::component(TOK_STATEMENT,
8026 [ + - ][ + - ]: 2 : new literal_number(addr, true)));
[ + - ][ + - ]
[ + - ]
8027 [ + - ][ + - ]: 2 : comps.push_back (new probe_point::component(TOK_ABSOLUTE));
[ + - ]
8028 : : }
8029 : : else
8030 : : {
8031 [ + - ]: 21297 : size_t pos = name.find(':');
8032 [ - + ]: 21297 : if (pos != string::npos)
8033 : : {
8034 [ # # ]: 0 : string module = name.substr(0, pos);
8035 [ # # ]: 0 : string function = name.substr(pos + 1);
8036 [ # # ][ # # ]: 0 : comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module)));
[ # # ][ # # ]
[ # # ]
8037 [ # # ][ # # ]: 0 : comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(function)));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
8038 : : }
8039 : : else
8040 [ + - ][ + - ]: 21297 : comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(name)));
[ + - ][ + - ]
[ + - ]
8041 : : }
8042 : :
8043 [ + + ]: 21299 : if (has_return)
8044 [ + - ][ + - ]: 10484 : comps.push_back (new probe_point::component(TOK_RETURN));
[ + - ]
8045 [ + + ]: 21299 : if (has_maxactive)
8046 [ + - ][ + - ]: 1 : comps.push_back (new probe_point::component(TOK_MAXACTIVE, new literal_number(maxactive_val)));
[ + - ][ + - ]
[ + - ]
8047 : :
8048 [ + - ]: 21299 : kprobe_var_expanding_visitor v (sess, has_return);
8049 [ + - ]: 21299 : v.replace (this->body);
8050 : :
8051 : : // If during target-variable-expanding the probe, we added a new block
8052 : : // of code, add it to the start of the probe.
8053 [ + + ]: 21299 : if (v.add_block)
8054 [ + - ][ + - ]: 254 : this->body = new block(v.add_block, this->body);
8055 : :
8056 : : // If when target-variable-expanding the probe, we need to
8057 : : // synthesize a sibling function-entry probe. We don't go through
8058 : : // the whole probe derivation business (PR10642) that could lead to
8059 : : // wildcard/alias resolution, or for that dwarf-induced duplication.
8060 [ + + ]: 21299 : if (v.add_call_probe)
8061 : : {
8062 [ - + ]: 254 : assert (has_return);
8063 : :
8064 : : // We temporarily replace base.
8065 : 254 : statement* old_body = base->body;
8066 : 254 : base->body = v.add_call_probe;
8067 : :
8068 : : derived_probe *entry_handler
8069 : : = new kprobe_derived_probe (sess, results, base, location, name, 0,
8070 : : false, has_statement, has_maxactive,
8071 : : has_path, has_library, maxactive_val,
8072 [ + - ][ + - ]: 254 : path, library);
8073 [ + - ]: 254 : results.push_back (entry_handler);
8074 : :
8075 : 254 : base->body = old_body;
8076 : : }
8077 : :
8078 [ + - ][ + - ]: 21299 : this->sole_location()->components = comps;
[ + - ][ + - ]
8079 : 21299 : }
8080 : :
8081 : 20708 : void kprobe_derived_probe::printsig (ostream& o) const
8082 : : {
8083 : 20708 : sole_location()->print (o);
8084 : 20708 : o << " /* " << " name = " << symbol_name << "*/";
8085 : 20708 : printsig_nested (o);
8086 : 20708 : }
8087 : :
8088 : 21299 : void kprobe_derived_probe::join_group (systemtap_session& s)
8089 : : {
8090 : :
8091 [ + + ]: 21299 : if (! s.kprobe_derived_probes)
8092 [ + - ]: 52 : s.kprobe_derived_probes = new kprobe_derived_probe_group ();
8093 : 21299 : s.kprobe_derived_probes->enroll (this);
8094 : :
8095 : 21299 : }
8096 : :
8097 : 21299 : void kprobe_derived_probe_group::enroll (kprobe_derived_probe* p)
8098 : : {
8099 [ + - ][ + - ]: 21299 : probes_by_module.insert (make_pair (p->symbol_name, p));
[ + - ][ + - ]
[ + - ]
8100 : : // probes of same symbol should share single kprobe/kretprobe
8101 : 21299 : }
8102 : :
8103 : : void
8104 : 12 : kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
8105 : : {
8106 [ + - ][ + - ]: 24 : if (probes_by_module.empty()) return;
8107 : :
8108 [ + - ][ + - ]: 12 : s.op->newline() << "/* ---- kprobe-based probes ---- */";
8109 : :
8110 : : // Warn of misconfigured kernels
8111 [ + - ][ + - ]: 12 : s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
8112 [ + - ][ + - ]: 12 : s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
8113 [ + - ][ + - ]: 12 : s.op->newline() << "#endif";
8114 [ + - ]: 12 : s.op->newline();
8115 : :
8116 [ + - ][ + - ]: 12 : s.op->newline() << "#ifndef KRETACTIVE";
8117 [ + - ][ + - ]: 12 : s.op->newline() << "#define KRETACTIVE (max(15,6*(int)num_possible_cpus()))";
8118 [ + - ][ + - ]: 12 : s.op->newline() << "#endif";
8119 : :
8120 : : // Forward declare the master entry functions
8121 [ + - ][ + - ]: 12 : s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
8122 [ + - ][ + - ]: 12 : s.op->line() << " struct pt_regs *regs);";
8123 [ + - ][ + - ]: 12 : s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
8124 [ + - ][ + - ]: 12 : s.op->line() << " struct pt_regs *regs);";
8125 : :
8126 : : // Emit an array of kprobe/kretprobe pointers
8127 [ + - ][ + - ]: 12 : s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
8128 [ + - ][ + - ]: 12 : s.op->newline() << "static void * stap_unreg_kprobes2[" << probes_by_module.size() << "];";
[ + - ][ + - ]
[ + - ]
8129 [ + - ][ + - ]: 12 : s.op->newline() << "#endif";
8130 : :
8131 : : // Emit the actual probe list.
8132 : :
8133 [ + - ][ + - ]: 12 : s.op->newline() << "static struct stap_dwarfless_kprobe {";
8134 [ + - ][ + - ]: 12 : s.op->newline(1) << "union { struct kprobe kp; struct kretprobe krp; } u;";
8135 [ + - ][ + - ]: 12 : s.op->newline() << "#ifdef __ia64__";
8136 [ + - ][ + - ]: 12 : s.op->newline() << "struct kprobe dummy;";
8137 [ + - ][ + - ]: 12 : s.op->newline() << "#endif";
8138 [ + - ][ + - ]: 12 : s.op->newline(-1) << "} stap_dwarfless_kprobes[" << probes_by_module.size() << "];";
[ + - ][ + - ]
[ + - ]
8139 : : // NB: bss!
8140 : :
8141 [ + - ][ + - ]: 12 : s.op->newline() << "static struct stap_dwarfless_probe {";
8142 [ + - ][ + - ]: 12 : s.op->newline(1) << "const unsigned return_p:1;";
8143 [ + - ][ + - ]: 12 : s.op->newline() << "const unsigned maxactive_p:1;";
8144 [ + - ][ + - ]: 12 : s.op->newline() << "const unsigned optional_p:1;";
8145 [ + - ][ + - ]: 12 : s.op->newline() << "unsigned registered_p:1;";
8146 [ + - ][ + - ]: 12 : s.op->newline() << "const unsigned short maxactive_val;";
8147 : :
8148 : : // Function Names are mostly small and uniform enough to justify putting
8149 : : // char[MAX]'s into the array instead of relocated char*'s.
8150 : :
8151 : 12 : size_t symbol_string_name_max = 0;
8152 : 12 : size_t symbol_string_name_tot = 0;
8153 [ + - ][ + - ]: 1211 : for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
[ + + ]
8154 : : {
8155 [ + - ]: 1199 : kprobe_derived_probe* p = it->second;
8156 : : #define DOIT(var,expr) do { \
8157 : : size_t var##_size = (expr) + 1; \
8158 : : var##_max = max (var##_max, var##_size); \
8159 : : var##_tot += var##_size; } while (0)
8160 [ + - ]: 1199 : DOIT(symbol_string_name, p->symbol_name.size());
8161 : : #undef DOIT
8162 : : }
8163 : :
8164 : : #define CALCIT(var) \
8165 : : s.op->newline() << "const char " << #var << "[" << var##_name_max << "] ;";
8166 : :
8167 [ + - ][ + - ]: 12 : CALCIT(symbol_string);
[ + - ][ + - ]
[ + - ][ + - ]
8168 : : #undef CALCIT
8169 : :
8170 [ + - ][ + - ]: 12 : s.op->newline() << "unsigned long address;";
8171 [ + - ][ + - ]: 12 : s.op->newline() << "const struct stap_probe * const probe;";
8172 [ + - ][ + - ]: 12 : s.op->newline(-1) << "} stap_dwarfless_probes[] = {";
8173 [ + - ]: 12 : s.op->indent(1);
8174 : :
8175 [ + - ][ + - ]: 1211 : for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
[ + + ]
8176 : : {
8177 [ + - ]: 1199 : kprobe_derived_probe* p = it->second;
8178 [ + - ][ + - ]: 1199 : s.op->newline() << "{";
8179 [ + + ]: 1199 : if (p->has_return)
8180 [ + - ][ + - ]: 589 : s.op->line() << " .return_p=1,";
8181 : :
8182 [ + + ]: 1199 : if (p->has_maxactive)
8183 : : {
8184 [ + - ][ + - ]: 1 : s.op->line() << " .maxactive_p=1,";
8185 [ + - ][ - + ]: 1 : assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
8186 [ + - ][ + - ]: 1 : s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
[ + - ][ + - ]
8187 : : }
8188 : :
8189 [ + + ]: 1199 : if (p->locations[0]->optional)
8190 [ + - ][ + - ]: 1151 : s.op->line() << " .optional_p=1,";
8191 : :
8192 [ + + ]: 1199 : if (p->has_statement)
8193 [ + - ][ + - ]: 2 : s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
[ + - ][ + - ]
[ + - ][ + - ]
8194 : : else
8195 [ + - ][ + - ]: 1197 : s.op->line() << " .symbol_string=\"" << p->symbol_name << "\",";
[ + - ][ + - ]
8196 : :
8197 [ + - ][ + - ]: 1199 : s.op->line() << " .probe=" << common_probe_init (p) << ",";
[ + - ][ + - ]
[ + - ][ + - ]
8198 [ + - ][ + - ]: 1199 : s.op->line() << " },";
8199 : : }
8200 : :
8201 [ + - ][ + - ]: 12 : s.op->newline(-1) << "};";
8202 : :
8203 : : // Emit the kprobes callback function
8204 [ + - ]: 12 : s.op->newline();
8205 [ + - ][ + - ]: 12 : s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
8206 [ + - ][ + - ]: 12 : s.op->line() << " struct pt_regs *regs) {";
8207 : : // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
8208 [ + - ][ + - ]: 12 : s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);";
8209 : : // Check that the index is plausible
8210 [ + - ][ + - ]: 12 : s.op->newline() << "struct stap_dwarfless_probe *sdp = &stap_dwarfless_probes[";
8211 [ + - ][ + - ]: 12 : s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
[ + - ][ + - ]
[ + - ]
8212 [ + - ][ + - ]: 12 : s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
8213 : : // XXX: it would be nice to give a more verbose error though; BUG_ON later?
8214 [ + - ][ + - ]: 12 : s.op->line() << "];";
8215 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sdp->probe",
8216 [ + - ][ + - ]: 12 : "stp_probe_type_kprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
8217 [ + - ][ + - ]: 12 : s.op->newline() << "c->kregs = regs;";
8218 : :
8219 : : // Make it look like the IP is set as it wouldn't have been replaced
8220 : : // by a breakpoint instruction when calling real probe handler. Reset
8221 : : // IP regs on return, so we don't confuse kprobes. PR10458
8222 [ + - ][ + - ]: 12 : s.op->newline() << "{";
8223 [ + - ]: 12 : s.op->indent(1);
8224 [ + - ][ + - ]: 12 : s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->kregs);";
8225 [ + - ][ + - ]: 12 : s.op->newline() << "SET_REG_IP(regs, (unsigned long) inst->addr);";
8226 [ + - ][ + - ]: 12 : s.op->newline() << "(*sdp->probe->ph) (c);";
8227 [ + - ][ + - ]: 12 : s.op->newline() << "SET_REG_IP(regs, kprobes_ip);";
8228 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8229 : :
8230 [ + - ]: 12 : common_probe_entryfn_epilogue (s, true);
8231 [ + - ][ + - ]: 12 : s.op->newline() << "return 0;";
8232 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8233 : :
8234 : : // Same for kretprobes
8235 [ + - ]: 12 : s.op->newline();
8236 [ + - ][ + - ]: 12 : s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
8237 [ + - ][ + - ]: 12 : s.op->line() << " struct pt_regs *regs) {";
8238 [ + - ][ + - ]: 12 : s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
8239 : :
8240 : : // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
8241 [ + - ][ + - ]: 12 : s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);";
8242 : : // Check that the index is plausible
8243 [ + - ][ + - ]: 12 : s.op->newline() << "struct stap_dwarfless_probe *sdp = &stap_dwarfless_probes[";
8244 [ + - ][ + - ]: 12 : s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
[ + - ][ + - ]
[ + - ]
8245 [ + - ][ + - ]: 12 : s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
8246 : : // XXX: it would be nice to give a more verbose error though; BUG_ON later?
8247 [ + - ][ + - ]: 12 : s.op->line() << "];";
8248 : :
8249 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sdp->probe",
8250 [ + - ][ + - ]: 12 : "stp_probe_type_kretprobe");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
8251 [ + - ][ + - ]: 12 : s.op->newline() << "c->kregs = regs;";
8252 [ + - ][ + - ]: 12 : s.op->newline() << "c->ips.krp.pi = inst;"; // for assisting runtime's backtrace logic
8253 : :
8254 : : // Make it look like the IP is set as it wouldn't have been replaced
8255 : : // by a breakpoint instruction when calling real probe handler. Reset
8256 : : // IP regs on return, so we don't confuse kprobes. PR10458
8257 [ + - ][ + - ]: 12 : s.op->newline() << "{";
8258 [ + - ]: 12 : s.op->indent(1);
8259 [ + - ][ + - ]: 12 : s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->kregs);";
8260 [ + - ][ + - ]: 12 : s.op->newline() << "SET_REG_IP(regs, (unsigned long) inst->rp->kp.addr);";
8261 [ + - ][ + - ]: 12 : s.op->newline() << "(*sdp->probe->ph) (c);";
8262 [ + - ][ + - ]: 12 : s.op->newline() << "SET_REG_IP(regs, kprobes_ip);";
8263 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8264 : :
8265 [ + - ]: 12 : common_probe_entryfn_epilogue (s, true);
8266 [ + - ][ + - ]: 12 : s.op->newline() << "return 0;";
8267 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8268 : :
8269 [ + - ][ + - ]: 12 : s.op->newline() << "#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL";
8270 [ + - ][ + - ]: 12 : s.op->newline() << "static int kprobe_resolve(void *data, const char *name,";
8271 [ + - ][ + - ]: 12 : s.op->newline() << " struct module *owner,";
8272 [ + - ][ + - ]: 12 : s.op->newline() << " unsigned long val) {";
8273 [ + - ][ + - ]: 12 : s.op->newline(1) << "int i;";
8274 [ + - ][ + - ]: 12 : s.op->newline() << "int *p = (int *) data;";
8275 [ + - ][ + - ]: 12 : s.op->newline() << "for (i=0; i<" << probes_by_module.size()
[ + - ][ + - ]
8276 [ + - ]: 12 : << " && *p > 0; i++) {";
8277 [ + - ][ + - ]: 12 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8278 [ + - ][ + - ]: 12 : s.op->newline() << "if (! sdp->address)";
8279 [ + - ][ + - ]: 12 : s.op->newline(1) << "if (strcmp(sdp->symbol_string, name) == 0) {";
8280 [ + - ][ + - ]: 12 : s.op->newline(1) << "sdp->address = val;";
8281 [ + - ][ + - ]: 12 : s.op->newline() << "(*p)--;";
8282 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8283 [ + - ][ + - ]: 12 : s.op->newline(-2) << "}";
8284 [ + - ][ + - ]: 12 : s.op->newline() << "return (p > 0) ? 0 : -1;";
8285 [ + - ][ + - ]: 12 : s.op->newline(-1) << "}";
8286 [ + - ][ + - ]: 12 : s.op->newline() << "#endif";
8287 : : }
8288 : :
8289 : :
8290 : : void
8291 : 12 : kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
8292 : : {
8293 : 12 : s.op->newline() << "#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL";
8294 : 12 : s.op->newline() << "{";
8295 : 12 : s.op->newline(1) << "int p = 0;";
8296 : 12 : s.op->newline() << "for (i = 0; i < " << probes_by_module.size() << "; i++) {";
8297 : 12 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8298 : 12 : s.op->newline() << "if (! sdp->address)";
8299 : 12 : s.op->newline(1) << "p++;";
8300 : 12 : s.op->newline(-2) << "}";
8301 : 12 : s.op->newline() << "kallsyms_on_each_symbol(kprobe_resolve, &p);";
8302 : 12 : s.op->newline(-1) << "}";
8303 : 12 : s.op->newline() << "#endif";
8304 : :
8305 : 12 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
8306 : 12 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8307 : 12 : s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
8308 : 12 : s.op->newline() << "void *addr = (void *) sdp->address;";
8309 : 12 : s.op->newline() << "const char *symbol_name = addr ? NULL : sdp->symbol_string;";
8310 : :
8311 : 12 : s.op->newline() << "#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL";
8312 : 12 : s.op->newline() << "if (! addr) {";
8313 : 12 : s.op->newline(1) << "sdp->registered_p = 0;";
8314 : 12 : s.op->newline() << "if (!sdp->optional_p)";
8315 : 12 : s.op->newline(1) << "_stp_warn (\"probe %s registration error (symbol not found)\", probe_point);";
8316 : 12 : s.op->newline(-1) << "continue;";
8317 : 12 : s.op->newline(-1) << "}";
8318 : 12 : s.op->newline() << "#endif";
8319 : :
8320 : 12 : s.op->newline() << "probe_point = sdp->probe->pp;"; // for error messages
8321 : 12 : s.op->newline() << "if (sdp->return_p) {";
8322 : 12 : s.op->newline(1) << "kp->u.krp.kp.addr = addr;";
8323 : 12 : s.op->newline() << "#ifdef STAPCONF_KPROBE_SYMBOL_NAME";
8324 : 12 : s.op->newline() << "kp->u.krp.kp.symbol_name = (char *) symbol_name;";
8325 : 12 : s.op->newline() << "#endif";
8326 : 12 : s.op->newline() << "if (sdp->maxactive_p) {";
8327 : 12 : s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
8328 : 12 : s.op->newline(-1) << "} else {";
8329 : 12 : s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;";
8330 : 12 : s.op->newline(-1) << "}";
8331 : 12 : s.op->newline() << "kp->u.krp.handler = &enter_kretprobe2_probe;";
8332 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
8333 : 12 : s.op->newline() << "#ifdef __ia64__";
8334 : 12 : s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;";
8335 : 12 : s.op->newline() << "#ifdef STAPCONF_KPROBE_SYMBOL_NAME";
8336 : 12 : s.op->newline() << "kp->dummy.symbol_name = kp->u.krp.kp.symbol_name;";
8337 : 12 : s.op->newline() << "#endif";
8338 : 12 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
8339 : 12 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
8340 : 12 : s.op->newline() << "if (rc == 0) {";
8341 : 12 : s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);";
8342 : 12 : s.op->newline() << "if (rc != 0)";
8343 : 12 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
8344 : 12 : s.op->newline(-2) << "}";
8345 : 12 : s.op->newline() << "#else";
8346 : 12 : s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
8347 : 12 : s.op->newline() << "#endif";
8348 : 12 : s.op->newline(-1) << "} else {";
8349 : : // to ensure safeness of bspcache, always use aggr_kprobe on ia64
8350 : 12 : s.op->newline(1) << "kp->u.kp.addr = addr;";
8351 : 12 : s.op->newline() << "#ifdef STAPCONF_KPROBE_SYMBOL_NAME";
8352 : 12 : s.op->newline() << "kp->u.kp.symbol_name = (char *) symbol_name;";
8353 : 12 : s.op->newline() << "#endif";
8354 : 12 : s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe2_probe;";
8355 : 12 : s.op->newline() << "#ifdef __ia64__";
8356 : 12 : s.op->newline() << "kp->dummy.pre_handler = NULL;";
8357 : 12 : s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
8358 : 12 : s.op->newline() << "#ifdef STAPCONF_KPROBE_SYMBOL_NAME";
8359 : 12 : s.op->newline() << "kp->dummy.symbol_name = kp->u.kp.symbol_name;";
8360 : 12 : s.op->newline() << "#endif";
8361 : 12 : s.op->newline() << "rc = register_kprobe (& kp->dummy);";
8362 : 12 : s.op->newline() << "if (rc == 0) {";
8363 : 12 : s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);";
8364 : 12 : s.op->newline() << "if (rc != 0)";
8365 : 12 : s.op->newline(1) << "unregister_kprobe (& kp->dummy);";
8366 : 12 : s.op->newline(-2) << "}";
8367 : 12 : s.op->newline() << "#else";
8368 : 12 : s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
8369 : 12 : s.op->newline() << "#endif";
8370 : 12 : s.op->newline(-1) << "}";
8371 : 12 : s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
8372 : 12 : s.op->newline(1) << "sdp->registered_p = 0;";
8373 : 12 : s.op->newline() << "if (!sdp->optional_p)";
8374 : 12 : s.op->newline(1) << "_stp_warn (\"probe %s (address 0x%lx) registration error (rc %d)\", probe_point, (unsigned long) addr, rc);";
8375 : 12 : s.op->newline(-1) << "rc = 0;"; // continue with other probes
8376 : : // XXX: shall we increment numskipped?
8377 : 12 : s.op->newline(-1) << "}";
8378 : :
8379 : 12 : s.op->newline() << "else sdp->registered_p = 1;";
8380 : 12 : s.op->newline(-1) << "}"; // for loop
8381 : 12 : }
8382 : :
8383 : :
8384 : : void
8385 : 16 : kprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
8386 : : {
8387 : : //Unregister kprobes by batch interfaces.
8388 : 16 : s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
8389 : 16 : s.op->newline() << "j = 0;";
8390 : 16 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
8391 : 16 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8392 : 16 : s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
8393 : 16 : s.op->newline() << "if (! sdp->registered_p) continue;";
8394 : 16 : s.op->newline() << "if (!sdp->return_p)";
8395 : 16 : s.op->newline(1) << "stap_unreg_kprobes2[j++] = &kp->u.kp;";
8396 : 16 : s.op->newline(-2) << "}";
8397 : 16 : s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes2, j);";
8398 : 16 : s.op->newline() << "j = 0;";
8399 : 16 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
8400 : 16 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8401 : 16 : s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
8402 : 16 : s.op->newline() << "if (! sdp->registered_p) continue;";
8403 : 16 : s.op->newline() << "if (sdp->return_p)";
8404 : 16 : s.op->newline(1) << "stap_unreg_kprobes2[j++] = &kp->u.krp;";
8405 : 16 : s.op->newline(-2) << "}";
8406 : 16 : s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes2, j);";
8407 : 16 : s.op->newline() << "#ifdef __ia64__";
8408 : 16 : s.op->newline() << "j = 0;";
8409 : 16 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
8410 : 16 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8411 : 16 : s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
8412 : 16 : s.op->newline() << "if (! sdp->registered_p) continue;";
8413 : 16 : s.op->newline() << "stap_unreg_kprobes2[j++] = &kp->dummy;";
8414 : 16 : s.op->newline(-1) << "}";
8415 : 16 : s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes2, j);";
8416 : 16 : s.op->newline() << "#endif";
8417 : 16 : s.op->newline() << "#endif";
8418 : :
8419 : 16 : s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
8420 : 16 : s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];";
8421 : 16 : s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];";
8422 : 16 : s.op->newline() << "if (! sdp->registered_p) continue;";
8423 : 16 : s.op->newline() << "if (sdp->return_p) {";
8424 : 16 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
8425 : 16 : s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
8426 : 16 : s.op->newline() << "#endif";
8427 : 16 : s.op->newline() << "atomic_add (kp->u.krp.nmissed, skipped_count());";
8428 : 16 : s.op->newline() << "#ifdef STP_TIMING";
8429 : 16 : s.op->newline() << "if (kp->u.krp.nmissed)";
8430 : 16 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->probe->pp, kp->u.krp.nmissed);";
8431 : 16 : s.op->newline(-1) << "#endif";
8432 : 16 : s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, skipped_count());";
8433 : 16 : s.op->newline() << "#ifdef STP_TIMING";
8434 : 16 : s.op->newline() << "if (kp->u.krp.kp.nmissed)";
8435 : 16 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->probe->pp, kp->u.krp.kp.nmissed);";
8436 : 16 : s.op->newline(-1) << "#endif";
8437 : 16 : s.op->newline(-1) << "} else {";
8438 : 16 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
8439 : 16 : s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
8440 : 16 : s.op->newline() << "#endif";
8441 : 16 : s.op->newline() << "atomic_add (kp->u.kp.nmissed, skipped_count());";
8442 : 16 : s.op->newline() << "#ifdef STP_TIMING";
8443 : 16 : s.op->newline() << "if (kp->u.kp.nmissed)";
8444 : 16 : s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->probe->pp, kp->u.kp.nmissed);";
8445 : 16 : s.op->newline(-1) << "#endif";
8446 : 16 : s.op->newline(-1) << "}";
8447 : 16 : s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
8448 : 16 : s.op->newline() << "unregister_kprobe (&kp->dummy);";
8449 : 16 : s.op->newline() << "#endif";
8450 : 16 : s.op->newline() << "sdp->registered_p = 0;";
8451 : 16 : s.op->newline(-1) << "}";
8452 : 16 : }
8453 : :
8454 [ # # ]: 0 : struct kprobe_builder: public derived_probe_builder
8455 : : {
8456 : : public:
8457 : 10962 : kprobe_builder() {}
8458 : :
8459 : 10962 : void build_no_more (systemtap_session &s) {}
8460 : :
8461 : : virtual void build(systemtap_session & sess,
8462 : : probe * base,
8463 : : probe_point * location,
8464 : : literal_map_t const & parameters,
8465 : : vector<derived_probe *> & finished_results);
8466 : : };
8467 : :
8468 : :
8469 : : void
8470 : 31417 : kprobe_builder::build(systemtap_session & sess,
8471 : : probe * base,
8472 : : probe_point * location,
8473 : : literal_map_t const & parameters,
8474 : : vector<derived_probe *> & finished_results)
8475 : : {
8476 [ + - ][ + - ]: 31417 : string function_string_val, module_string_val;
8477 [ + - ][ + - ]: 31417 : string path, library, path_tgt, library_tgt;
[ + - ][ + - ]
8478 : 31417 : int64_t statement_num_val = 0, maxactive_val = 0;
8479 : : bool has_function_str, has_module_str, has_statement_num;
8480 : : bool has_absolute, has_return, has_maxactive;
8481 : : bool has_path, has_library;
8482 : :
8483 [ + - ]: 31417 : has_function_str = get_param(parameters, TOK_FUNCTION, function_string_val);
8484 [ + - ]: 31417 : has_module_str = get_param(parameters, TOK_MODULE, module_string_val);
8485 [ + - ]: 31417 : has_return = has_null_param (parameters, TOK_RETURN);
8486 [ + - ]: 31417 : has_maxactive = get_param(parameters, TOK_MAXACTIVE, maxactive_val);
8487 [ + - ]: 31417 : has_statement_num = get_param(parameters, TOK_STATEMENT, statement_num_val);
8488 [ + - ]: 31417 : has_absolute = has_null_param (parameters, TOK_ABSOLUTE);
8489 [ + - ]: 31417 : has_path = get_param (parameters, TOK_PROCESS, path);
8490 [ + - ]: 31417 : has_library = get_param (parameters, TOK_LIBRARY, library);
8491 : :
8492 [ - + ]: 31417 : if (has_path)
8493 : : {
8494 [ # # ][ # # ]: 0 : path = find_executable (path, sess.sysroot, sess.sysenv);
[ # # ][ # # ]
[ # # ]
8495 [ # # ][ # # ]: 0 : path_tgt = path_remove_sysroot(sess, path);
[ # # ]
8496 : : }
8497 [ - + ]: 31417 : if (has_library)
8498 : : {
8499 : : library = find_executable (library, sess.sysroot, sess.sysenv,
8500 [ # # ][ # # ]: 0 : "LD_LIBRARY_PATH");
[ # # ][ # # ]
[ # # ]
8501 [ # # ][ # # ]: 0 : library_tgt = path_remove_sysroot(sess, library);
[ # # ]
8502 : : }
8503 : :
8504 [ + + ]: 31417 : if (has_function_str)
8505 : : {
8506 [ - + ]: 31415 : if (has_module_str)
8507 : : {
8508 [ # # ][ # # ]: 0 : function_string_val = module_string_val + ":" + function_string_val;
[ # # ][ # # ]
[ # # ]
8509 : : derived_probe *dp
8510 : : = new kprobe_derived_probe (sess, finished_results, base,
8511 : : location, function_string_val,
8512 : : 0, has_return, has_statement_num,
8513 : : has_maxactive, has_path, has_library,
8514 [ # # ][ # # ]: 0 : maxactive_val, path_tgt, library_tgt);
8515 [ # # ]: 0 : finished_results.push_back (dp);
8516 : : }
8517 : : else
8518 : : {
8519 [ + - ]: 31415 : vector<string> matches;
8520 : :
8521 : : // Simple names can be found directly
8522 [ + - ][ + - ]: 31415 : if (function_string_val.find_first_of("*?[") == string::npos)
8523 : : {
8524 [ + - ][ + + ]: 31415 : if (sess.kernel_functions.count(function_string_val))
8525 [ + - ]: 21043 : matches.push_back(function_string_val);
8526 : : }
8527 : : else // Search function name list for matching names
8528 : : {
8529 [ # # ][ # # ]: 0 : for (set<string>::const_iterator it = sess.kernel_functions.begin();
8530 [ # # ]: 0 : it != sess.kernel_functions.end(); it++)
8531 : : // fnmatch returns zero for matching.
8532 [ # # ][ # # ]: 0 : if (fnmatch(function_string_val.c_str(), it->c_str(), 0) == 0)
[ # # ][ # # ]
[ # # ]
8533 [ # # ]: 0 : matches.push_back(*it);
8534 : : }
8535 : :
8536 [ + - ][ + - ]: 104916 : for (vector<string>::const_iterator it = matches.begin();
[ + - ][ + - ]
[ + + ]
8537 [ + - ]: 52458 : it != matches.end(); it++)
8538 : : {
8539 : : derived_probe *dp
8540 : : = new kprobe_derived_probe (sess, finished_results, base,
8541 : : location, *it, 0, has_return,
8542 : : has_statement_num,
8543 : : has_maxactive, has_path,
8544 : : has_library, maxactive_val,
8545 [ + - ][ + - ]: 21043 : path_tgt, library_tgt);
8546 [ + - ]: 21043 : finished_results.push_back (dp);
8547 [ + - ]: 31415 : }
8548 : : }
8549 : : }
8550 : : else
8551 : : {
8552 : : // assert guru mode for absolute probes
8553 [ + - ][ + - ]: 2 : if ( has_statement_num && has_absolute && !base->privileged )
[ - + ]
8554 [ # # ][ # # ]: 0 : throw semantic_error (_("absolute statement probe in unprivileged script; need stap -g"), base->tok);
8555 : :
8556 : : finished_results.push_back (new kprobe_derived_probe (sess,
8557 : : finished_results,
8558 : : base,
8559 : : location, "",
8560 : : statement_num_val,
8561 : : has_return,
8562 : : has_statement_num,
8563 : : has_maxactive,
8564 : : has_path,
8565 : : has_library,
8566 : : maxactive_val,
8567 : : path_tgt,
8568 [ + - ][ + - ]: 2 : library_tgt));
[ + - ][ + - ]
[ + - ]
8569 [ + - ][ + - ]: 31417 : }
[ + - ][ + - ]
[ + - ][ + - ]
8570 : 31417 : }
8571 : :
8572 : :
8573 : : void
8574 : 399 : kprobe_var_expanding_visitor::visit_entry_op (entry_op *e)
8575 : : {
8576 : 399 : expression *repl = e;
8577 : :
8578 [ + + ]: 399 : if (has_return)
8579 : : {
8580 : : // expand the operand as if it weren't a return probe
8581 : 398 : has_return = false;
8582 : 398 : replace (e->operand);
8583 : 398 : has_return = true;
8584 : :
8585 : : // XXX it would be nice to use gen_kretprobe_saved_return when
8586 : : // available, but it requires knowing the types already, which is
8587 : : // problematic for arbitrary expressons.
8588 : : repl = gen_mapped_saved_return (sess, e->operand, "entry",
8589 : : add_block, add_block_tid,
8590 [ + - ][ + - ]: 398 : add_call_probe, add_call_probe_tid);
[ + - ]
8591 : : }
8592 : 399 : provide (repl);
8593 : 399 : }
8594 : :
8595 : :
8596 : : // ------------------------------------------------------------------------
8597 : : // Hardware breakpoint based probes.
8598 : : // ------------------------------------------------------------------------
8599 : :
8600 [ + - ]: 2414 : static const string TOK_HWBKPT("data");
8601 [ + - ]: 2414 : static const string TOK_HWBKPT_WRITE("write");
8602 [ + - ]: 2414 : static const string TOK_HWBKPT_RW("rw");
8603 [ + - ]: 2414 : static const string TOK_LENGTH("length");
8604 : :
8605 : : #define HWBKPT_READ 0
8606 : : #define HWBKPT_WRITE 1
8607 : : #define HWBKPT_RW 2
8608 [ # # ][ # # ]: 0 : struct hwbkpt_derived_probe: public derived_probe
8609 : : {
8610 : : hwbkpt_derived_probe (probe *base,
8611 : : probe_point *location,
8612 : : uint64_t addr,
8613 : : string symname,
8614 : : unsigned int len,
8615 : : bool has_only_read_access,
8616 : : bool has_only_write_access,
8617 : : bool has_rw_access
8618 : : );
8619 : : Dwarf_Addr hwbkpt_addr;
8620 : : string symbol_name;
8621 : : unsigned int hwbkpt_access,hwbkpt_len;
8622 : :
8623 : : void printsig (std::ostream &o) const;
8624 : : void join_group (systemtap_session& s);
8625 : : };
8626 : :
8627 [ # # ][ # # ]: 3 : struct hwbkpt_derived_probe_group: public derived_probe_group
[ + - ]
8628 : : {
8629 : : private:
8630 : : vector<hwbkpt_derived_probe*> hwbkpt_probes;
8631 : :
8632 : : public:
8633 : : void enroll (hwbkpt_derived_probe* probe, systemtap_session& s);
8634 : : void emit_module_decls (systemtap_session& s);
8635 : : void emit_module_init (systemtap_session& s);
8636 : : void emit_module_exit (systemtap_session& s);
8637 : : };
8638 : :
8639 : 4 : hwbkpt_derived_probe::hwbkpt_derived_probe (probe *base,
8640 : : probe_point *location,
8641 : : uint64_t addr,
8642 : : string symname,
8643 : : unsigned int len,
8644 : : bool has_only_read_access,
8645 : : bool has_only_write_access,
8646 : : bool):
8647 : : derived_probe (base, location, true /* .components soon rewritten */ ),
8648 : : hwbkpt_addr (addr),
8649 : : symbol_name (symname),
8650 [ + - ]: 4 : hwbkpt_len (len)
8651 : : {
8652 : 4 : this->tok = base->tok;
8653 : :
8654 [ + - ]: 4 : vector<probe_point::component*> comps;
8655 [ + - ][ + - ]: 4 : comps.push_back (new probe_point::component(TOK_KERNEL));
[ + - ]
8656 : :
8657 [ - + ]: 4 : if (hwbkpt_addr)
8658 : : comps.push_back (new probe_point::component (TOK_HWBKPT,
8659 [ # # ][ # # ]: 0 : new literal_number(hwbkpt_addr, true)));
[ # # ][ # # ]
[ # # ]
8660 [ + - ][ + - ]: 4 : else if (symbol_name.size())
8661 [ + - ][ + - ]: 4 : comps.push_back (new probe_point::component (TOK_HWBKPT, new literal_string(symbol_name)));
[ + - ][ + - ]
[ + - ]
8662 : :
8663 [ + - ][ + - ]: 4 : comps.push_back (new probe_point::component (TOK_LENGTH, new literal_number(hwbkpt_len)));
[ + - ][ + - ]
[ + - ]
8664 : :
8665 [ - + ]: 4 : if (has_only_read_access)
8666 : 0 : this->hwbkpt_access = HWBKPT_READ ;
8667 : : //TODO add code for comps.push_back for read, since this flag is not for x86
8668 : :
8669 : : else
8670 : : {
8671 [ + + ]: 4 : if (has_only_write_access)
8672 : : {
8673 : 1 : this->hwbkpt_access = HWBKPT_WRITE ;
8674 [ + - ][ + - ]: 1 : comps.push_back (new probe_point::component(TOK_HWBKPT_WRITE));
[ + - ]
8675 : : }
8676 : : else
8677 : : {
8678 : 3 : this->hwbkpt_access = HWBKPT_RW ;
8679 [ + - ][ + - ]: 3 : comps.push_back (new probe_point::component(TOK_HWBKPT_RW));
[ + - ]
8680 : : }
8681 : : }
8682 : :
8683 [ + - ][ + - ]: 4 : this->sole_location()->components = comps;
[ + - ]
8684 : 4 : }
8685 : :
8686 : 4 : void hwbkpt_derived_probe::printsig (ostream& o) const
8687 : : {
8688 : 4 : sole_location()->print (o);
8689 : 4 : printsig_nested (o);
8690 : 4 : }
8691 : :
8692 : 4 : void hwbkpt_derived_probe::join_group (systemtap_session& s)
8693 : : {
8694 [ + + ]: 4 : if (! s.hwbkpt_derived_probes)
8695 [ + - ]: 3 : s.hwbkpt_derived_probes = new hwbkpt_derived_probe_group ();
8696 : 4 : s.hwbkpt_derived_probes->enroll (this, s);
8697 : 4 : }
8698 : :
8699 : 4 : void hwbkpt_derived_probe_group::enroll (hwbkpt_derived_probe* p, systemtap_session& s)
8700 : : {
8701 : 4 : hwbkpt_probes.push_back (p);
8702 : :
8703 : 4 : unsigned max_hwbkpt_probes_by_arch = 0;
8704 [ + - ][ - + ]: 4 : if (s.architecture == "i386" || s.architecture == "x86_64")
[ - + ]
8705 : 0 : max_hwbkpt_probes_by_arch = 4;
8706 [ - + ]: 4 : else if (s.architecture == "s390")
8707 : 0 : max_hwbkpt_probes_by_arch = 1;
8708 : :
8709 [ + - ]: 4 : if (hwbkpt_probes.size() >= max_hwbkpt_probes_by_arch)
8710 : 4 : s.print_warning (_F("Too many hardware breakpoint probes requested for %s (%zu vs. %u)",
8711 [ + - ]: 4 : s.architecture.c_str(), hwbkpt_probes.size(), max_hwbkpt_probes_by_arch));
8712 : 4 : }
8713 : :
8714 : : void
8715 : 2 : hwbkpt_derived_probe_group::emit_module_decls (systemtap_session& s)
8716 : : {
8717 [ - + ]: 4 : if (hwbkpt_probes.empty()) return;
8718 : :
8719 : 2 : s.op->newline() << "/* ---- hwbkpt-based probes ---- */";
8720 : :
8721 : 2 : s.op->newline() << "#include <linux/perf_event.h>";
8722 : 2 : s.op->newline() << "#include <linux/hw_breakpoint.h>";
8723 : 2 : s.op->newline();
8724 : :
8725 : : // Forward declare the master entry functions
8726 : 2 : s.op->newline() << "static int enter_hwbkpt_probe (struct perf_event *bp,";
8727 : 2 : s.op->line() << " int nmi,";
8728 : 2 : s.op->line() << " struct perf_sample_data *data,";
8729 : 2 : s.op->line() << " struct pt_regs *regs);";
8730 : :
8731 : : // Emit the actual probe list.
8732 : :
8733 : 2 : s.op->newline() << "static struct perf_event_attr ";
8734 : 2 : s.op->newline() << "stap_hwbkpt_probe_array[" << hwbkpt_probes.size() << "];";
8735 : :
8736 : 2 : s.op->newline() << "static struct perf_event **";
8737 : 2 : s.op->newline() << "stap_hwbkpt_ret_array[" << hwbkpt_probes.size() << "];";
8738 : 2 : s.op->newline() << "static struct stap_hwbkpt_probe {";
8739 : 2 : s.op->newline() << "int registered_p:1;";
8740 : : // registered_p = 0 signifies a probe that is unregistered (or failed)
8741 : : // registered_p = 1 signifies a probe that got registered successfully
8742 : :
8743 : : // Symbol Names are mostly small and uniform enough
8744 : : // to justify putting const char*.
8745 : 2 : s.op->newline() << "const char * const symbol;";
8746 : :
8747 : 2 : s.op->newline() << "const unsigned long address;";
8748 : 2 : s.op->newline() << "uint8_t atype;";
8749 : 2 : s.op->newline() << "unsigned int len;";
8750 : 2 : s.op->newline() << "const struct stap_probe * const probe;";
8751 : 2 : s.op->newline() << "} stap_hwbkpt_probes[] = {";
8752 : 2 : s.op->indent(1);
8753 : :
8754 [ + + ]: 5 : for (unsigned int it = 0; it < hwbkpt_probes.size(); it++)
8755 : : {
8756 : 3 : hwbkpt_derived_probe* p = hwbkpt_probes.at(it);
8757 : 3 : s.op->newline() << "{";
8758 [ + - ]: 3 : if (p->symbol_name.size())
8759 : 3 : s.op->line() << " .address=(unsigned long)0x0" << "ULL,";
8760 : : else
8761 : 0 : s.op->line() << " .address=(unsigned long)0x" << hex << p->hwbkpt_addr << dec << "ULL,";
8762 [ - + + - ]: 3 : switch(p->hwbkpt_access){
8763 : : case HWBKPT_READ:
8764 : 0 : s.op->line() << " .atype=HW_BREAKPOINT_R ,";
8765 : 0 : break;
8766 : : case HWBKPT_WRITE:
8767 : 1 : s.op->line() << " .atype=HW_BREAKPOINT_W ,";
8768 : 1 : break;
8769 : : case HWBKPT_RW:
8770 : 2 : s.op->line() << " .atype=HW_BREAKPOINT_R|HW_BREAKPOINT_W ,";
8771 : 2 : break;
8772 : : };
8773 : 3 : s.op->line() << " .len=" << p->hwbkpt_len << ",";
8774 [ + - ][ + - ]: 3 : s.op->line() << " .probe=" << common_probe_init (p) << ",";
8775 : 3 : s.op->line() << " .symbol=\"" << p->symbol_name << "\",";
8776 : 3 : s.op->line() << " },";
8777 : : }
8778 : 2 : s.op->newline(-1) << "};";
8779 : :
8780 : : // Emit the hwbkpt callback function
8781 : 2 : s.op->newline() ;
8782 : 2 : s.op->newline() << "static int enter_hwbkpt_probe (struct perf_event *bp,";
8783 : 2 : s.op->line() << " int nmi,";
8784 : 2 : s.op->line() << " struct perf_sample_data *data,";
8785 : 2 : s.op->line() << " struct pt_regs *regs) {";
8786 : 2 : s.op->newline(1) << "unsigned int i;";
8787 : 2 : s.op->newline() << "if (bp->attr.type != PERF_TYPE_BREAKPOINT) return -1;";
8788 : 2 : s.op->newline() << "for (i=0; i<" << hwbkpt_probes.size() << "; i++) {";
8789 : 2 : s.op->newline(1) << "struct perf_event_attr *hp = & stap_hwbkpt_probe_array[i];";
8790 : : // XXX: why not match stap_hwbkpt_ret_array[i] against bp instead?
8791 : 2 : 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) {";
8792 : 2 : s.op->newline(1) << "struct stap_hwbkpt_probe *sdp = &stap_hwbkpt_probes[i];";
8793 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "sdp->probe",
8794 [ + - ][ + - ]: 2 : "stp_probe_type_hwbkpt");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
8795 : 2 : s.op->newline() << "if (user_mode(regs)) {";
8796 : 2 : s.op->newline(1)<< "c->user_mode_p = 1;";
8797 : 2 : s.op->newline() << "c->uregs = regs;";
8798 : 2 : s.op->newline(-1) << "} else {";
8799 : 2 : s.op->newline(1) << "c->kregs = regs;";
8800 : 2 : s.op->newline(-1) << "}";
8801 : 2 : s.op->newline() << "(*sdp->probe->ph) (c);";
8802 : 2 : common_probe_entryfn_epilogue (s, true);
8803 : 2 : s.op->newline(-1) << "}";
8804 : 2 : s.op->newline(-1) << "}";
8805 : 2 : s.op->newline() << "return 0;";
8806 : 2 : s.op->newline(-1) << "}";
8807 : : }
8808 : :
8809 : : void
8810 : 2 : hwbkpt_derived_probe_group::emit_module_init (systemtap_session& s)
8811 : : {
8812 : 2 : s.op->newline() << "for (i=0; i<" << hwbkpt_probes.size() << "; i++) {";
8813 : 2 : s.op->newline(1) << "struct stap_hwbkpt_probe *sdp = & stap_hwbkpt_probes[i];";
8814 : 2 : s.op->newline() << "struct perf_event_attr *hp = & stap_hwbkpt_probe_array[i];";
8815 : 2 : s.op->newline() << "void *addr = (void *) sdp->address;";
8816 : 2 : s.op->newline() << "const char *hwbkpt_symbol_name = addr ? NULL : sdp->symbol;";
8817 : 2 : s.op->newline() << "hw_breakpoint_init(hp);";
8818 : 2 : s.op->newline() << "if (addr)";
8819 : 2 : s.op->newline(1) << "hp->bp_addr = (unsigned long) addr;";
8820 : 2 : s.op->newline(-1) << "else { ";
8821 : 2 : s.op->newline(1) << "hp->bp_addr = kallsyms_lookup_name(hwbkpt_symbol_name);";
8822 : 2 : s.op->newline() << "if (!hp->bp_addr) { ";
8823 : 2 : s.op->newline(1) << "_stp_warn(\"Probe %s registration skipped: invalid symbol %s \",sdp->probe->pp,hwbkpt_symbol_name);";
8824 : 2 : s.op->newline() << "continue;";
8825 : 2 : s.op->newline(-1) << "}";
8826 : 2 : s.op->newline(-1) << "}";
8827 : 2 : s.op->newline() << "hp->bp_type = sdp->atype;";
8828 : :
8829 : : // On x86 & x86-64, hp->bp_len is not just a number but a macro/enum (!?!).
8830 [ + - ][ - + ]: 2 : if (s.architecture == "i386" || s.architecture == "x86_64" )
[ - + ]
8831 : : {
8832 : 0 : s.op->newline() << "switch(sdp->len) {";
8833 : 0 : s.op->newline() << "case 1:";
8834 : 0 : s.op->newline(1) << "hp->bp_len = HW_BREAKPOINT_LEN_1;";
8835 : 0 : s.op->newline() << "break;";
8836 : 0 : s.op->newline(-1) << "case 2:";
8837 : 0 : s.op->newline(1) << "hp->bp_len = HW_BREAKPOINT_LEN_2;";
8838 : 0 : s.op->newline() << "break;";
8839 : 0 : s.op->newline(-1) << "case 3:";
8840 : 0 : s.op->newline() << "case 4:";
8841 : 0 : s.op->newline(1) << "hp->bp_len = HW_BREAKPOINT_LEN_4;";
8842 : 0 : s.op->newline() << "break;";
8843 : 0 : s.op->newline(-1) << "case 5:";
8844 : 0 : s.op->newline() << "case 6:";
8845 : 0 : s.op->newline() << "case 7:";
8846 : 0 : s.op->newline() << "case 8:";
8847 : 0 : s.op->newline() << "default:"; // XXX: could instead reject
8848 : 0 : s.op->newline(1) << "hp->bp_len = HW_BREAKPOINT_LEN_8;";
8849 : 0 : s.op->newline() << "break;";
8850 : 0 : s.op->newline(-1) << "}";
8851 : : }
8852 : : else // other architectures presumed straightforward
8853 : 2 : s.op->newline() << "hp->bp_len = sdp->len;";
8854 : :
8855 : 2 : s.op->newline() << "probe_point = sdp->probe->pp;"; // for error messages
8856 : 2 : s.op->newline() << "#ifdef STAPCONF_HW_BREAKPOINT_CONTEXT";
8857 : 2 : s.op->newline() << "stap_hwbkpt_ret_array[i] = register_wide_hw_breakpoint(hp, (void *)&enter_hwbkpt_probe, NULL);";
8858 : 2 : s.op->newline() << "#else";
8859 : 2 : s.op->newline() << "stap_hwbkpt_ret_array[i] = register_wide_hw_breakpoint(hp, (void *)&enter_hwbkpt_probe);";
8860 : 2 : s.op->newline() << "#endif";
8861 : 2 : s.op->newline() << "rc = 0;";
8862 : 2 : s.op->newline() << "if (IS_ERR(stap_hwbkpt_ret_array[i])) {";
8863 : 2 : s.op->newline(1) << "rc = PTR_ERR(stap_hwbkpt_ret_array[i]);";
8864 : 2 : s.op->newline() << "stap_hwbkpt_ret_array[i] = 0;";
8865 : 2 : s.op->newline(-1) << "}";
8866 : 2 : s.op->newline() << "if (rc) {";
8867 : 2 : s.op->newline(1) << "_stp_warn(\"Hwbkpt probe %s: registration error %d, addr %p, name %s\", probe_point, rc, addr, hwbkpt_symbol_name);";
8868 : 2 : s.op->newline() << "sdp->registered_p = 0;";
8869 : 2 : s.op->newline(-1) << "}";
8870 : 2 : s.op->newline() << " else sdp->registered_p = 1;";
8871 : 2 : s.op->newline(-1) << "}"; // for loop
8872 : 2 : }
8873 : :
8874 : : void
8875 : 2 : hwbkpt_derived_probe_group::emit_module_exit (systemtap_session& s)
8876 : : {
8877 : : //Unregister hwbkpt probes.
8878 : 2 : s.op->newline() << "for (i=0; i<" << hwbkpt_probes.size() << "; i++) {";
8879 : 2 : s.op->newline(1) << "struct stap_hwbkpt_probe *sdp = & stap_hwbkpt_probes[i];";
8880 : 2 : s.op->newline() << "if (sdp->registered_p == 0) continue;";
8881 : 2 : s.op->newline() << "unregister_wide_hw_breakpoint(stap_hwbkpt_ret_array[i]);";
8882 : 2 : s.op->newline() << "sdp->registered_p = 0;";
8883 : 2 : s.op->newline(-1) << "}";
8884 : 2 : }
8885 : :
8886 [ # # ]: 0 : struct hwbkpt_builder: public derived_probe_builder
8887 : : {
8888 : 7308 : hwbkpt_builder() {}
8889 : : virtual void build(systemtap_session & sess,
8890 : : probe * base,
8891 : : probe_point * location,
8892 : : literal_map_t const & parameters,
8893 : : vector<derived_probe *> & finished_results);
8894 : : };
8895 : :
8896 : : void
8897 : 4 : hwbkpt_builder::build(systemtap_session & sess,
8898 : : probe * base,
8899 : : probe_point * location,
8900 : : literal_map_t const & parameters,
8901 : : vector<derived_probe *> & finished_results)
8902 : : {
8903 [ + - ]: 4 : string symbol_str_val;
8904 : : int64_t hwbkpt_address, len;
8905 : : bool has_addr, has_symbol_str, has_write, has_rw, has_len;
8906 : :
8907 [ + - ][ + - ]: 4 : if (! (sess.kernel_config["CONFIG_PERF_EVENTS"] == string("y")))
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
8908 : 0 : throw semantic_error (_("CONFIG_PERF_EVENTS not available on this kernel"),
8909 [ # # ][ # # ]: 0 : location->components[0]->tok);
8910 [ + - ][ + - ]: 4 : if (! (sess.kernel_config["CONFIG_HAVE_HW_BREAKPOINT"] == string("y")))
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
8911 : 0 : throw semantic_error (_("CONFIG_HAVE_HW_BREAKPOINT not available on this kernel"),
8912 [ # # ][ # # ]: 0 : location->components[0]->tok);
8913 : :
8914 [ + - ]: 4 : has_addr = get_param (parameters, TOK_HWBKPT, hwbkpt_address);
8915 [ + - ]: 4 : has_symbol_str = get_param (parameters, TOK_HWBKPT, symbol_str_val);
8916 [ + - ]: 4 : has_len = get_param (parameters, TOK_LENGTH, len);
8917 [ + - ][ + - ]: 4 : has_write = (parameters.find(TOK_HWBKPT_WRITE) != parameters.end());
8918 [ + - ][ + - ]: 4 : has_rw = (parameters.find(TOK_HWBKPT_RW) != parameters.end());
8919 : :
8920 [ + - ]: 4 : if (!has_len)
8921 : 4 : len = 1;
8922 : :
8923 [ - + ]: 4 : if (has_addr)
8924 : : finished_results.push_back (new hwbkpt_derived_probe (base,
8925 : : location,
8926 : : hwbkpt_address,
8927 : : "",len,0,
8928 : : has_write,
8929 [ # # ][ # # ]: 0 : has_rw));
[ # # ][ # # ]
[ # # ]
8930 [ + - ]: 4 : else if (has_symbol_str)
8931 : : finished_results.push_back (new hwbkpt_derived_probe (base,
8932 : : location,
8933 : : 0,
8934 : : symbol_str_val,len,0,
8935 : : has_write,
8936 [ + - ][ + - ]: 4 : has_rw));
[ + - ][ + - ]
[ + - ]
8937 : : else
8938 [ + - ]: 4 : assert (0);
8939 : 4 : }
8940 : :
8941 : : // ------------------------------------------------------------------------
8942 : : // statically inserted kernel-tracepoint derived probes
8943 : : // ------------------------------------------------------------------------
8944 : :
8945 [ + - ][ + - ]: 16720 : struct tracepoint_arg
[ + - ][ + - ]
8946 : : {
8947 : : string name, c_type, typecast;
8948 : : bool usable, used, isptr;
8949 : : Dwarf_Die type_die;
8950 [ + - ][ + - ]: 4732 : tracepoint_arg(): usable(false), used(false), isptr(false) {}
8951 : : };
8952 : :
8953 [ # # ][ # # ]: 0 : struct tracepoint_derived_probe: public derived_probe
[ # # ][ # # ]
8954 : : {
8955 : : tracepoint_derived_probe (systemtap_session& s,
8956 : : dwflpp& dw, Dwarf_Die& func_die,
8957 : : const string& tracepoint_name,
8958 : : probe* base_probe, probe_point* location);
8959 : :
8960 : : systemtap_session& sess;
8961 : : string tracepoint_name, header;
8962 : : vector <struct tracepoint_arg> args;
8963 : :
8964 : : void build_args(dwflpp& dw, Dwarf_Die& func_die);
8965 : : void getargs (std::list<std::string> &arg_set) const;
8966 : : void join_group (systemtap_session& s);
8967 : : void print_dupe_stamp(ostream& o);
8968 : : };
8969 : :
8970 : :
8971 [ # # ]: 77 : struct tracepoint_derived_probe_group: public generic_dpg<tracepoint_derived_probe>
8972 : : {
8973 : : void emit_module_decls (systemtap_session& s);
8974 : : void emit_module_init (systemtap_session& s);
8975 : : void emit_module_exit (systemtap_session& s);
8976 : : };
8977 : :
8978 : :
8979 [ - + ]: 1925 : struct tracepoint_var_expanding_visitor: public var_expanding_visitor
8980 : : {
8981 : 1925 : tracepoint_var_expanding_visitor(dwflpp& dw, const string& probe_name,
8982 : : vector <struct tracepoint_arg>& args):
8983 : 1925 : dw (dw), probe_name (probe_name), args (args) {}
8984 : : dwflpp& dw;
8985 : : const string& probe_name;
8986 : : vector <struct tracepoint_arg>& args;
8987 : :
8988 : : void visit_target_symbol (target_symbol* e);
8989 : : void visit_target_symbol_arg (target_symbol* e);
8990 : : void visit_target_symbol_context (target_symbol* e);
8991 : : };
8992 : :
8993 : :
8994 : : void
8995 : 6073 : tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
8996 : : {
8997 [ + - ]: 6073 : string argname = e->sym_name();
8998 : :
8999 : : // search for a tracepoint parameter matching this name
9000 : 6073 : tracepoint_arg *arg = NULL;
9001 [ + + ]: 13589 : for (unsigned i = 0; i < args.size(); ++i)
9002 [ + - ][ + - ]: 12790 : if (args[i].usable && args[i].name == argname)
[ + + ][ + + ]
9003 : : {
9004 : 5274 : arg = &args[i];
9005 : 5274 : arg->used = true;
9006 : 5274 : break;
9007 : : }
9008 : :
9009 [ + + ]: 6073 : if (arg == NULL)
9010 : : {
9011 [ + - ]: 799 : stringstream alternatives;
9012 [ + + ]: 2731 : for (unsigned i = 0; i < args.size(); ++i)
9013 [ + - ][ + - ]: 1932 : alternatives << " $" << args[i].name;
9014 [ + - ]: 799 : alternatives << " $$name $$parms $$vars";
9015 : :
9016 : : // We hope that this value ends up not being referenced after all, so it
9017 : : // can be optimized out quietly.
9018 : 799 : throw semantic_error(_F("unable to find tracepoint variable '%s' (alternatives: %s)",
9019 [ + - ][ + - ]: 799 : e->name.c_str(), alternatives.str().c_str()), e->tok);
[ + - ][ + - ]
[ + - ]
9020 : : // NB: we can have multiple errors, since a target variable
9021 : : // may be expanded in several different contexts:
9022 : : // trace ("*") { $foo->bar }
9023 : : }
9024 : :
9025 : : // make sure we're not dereferencing base types
9026 [ + + ]: 5274 : if (!arg->isptr)
9027 [ + - ][ + - ]: 2392 : e->assert_no_components("tracepoint", true);
[ + - ]
9028 : :
9029 : : // we can only write to dereferenced fields, and only if guru mode is on
9030 [ + - ]: 5274 : bool lvalue = is_active_lvalue(e);
9031 [ - + ][ # # ]: 5274 : if (lvalue && (!dw.sess.guru_mode || e->components.empty()))
[ # # ][ # # ]
[ - + ]
9032 [ # # ][ # # ]: 0 : throw semantic_error(_F("write to tracepoint variable '%s' not permitted; need stap -g", e->name.c_str()), e->tok);
[ # # ]
9033 : :
9034 : : // XXX: if a struct/union arg is passed by value, then writing to its fields
9035 : : // is also meaningless until you dereference past a pointer member. It's
9036 : : // harder to detect and prevent that though...
9037 : :
9038 [ + - ][ + + ]: 5274 : if (e->components.empty())
9039 : : {
9040 [ - + ]: 4075 : if (e->addressof)
9041 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of tracepoint variable"), e->tok);
9042 : :
9043 : : // Just grab the value from the probe locals
9044 [ + - ][ + - ]: 4075 : symbol* sym = new symbol;
9045 : 4075 : sym->tok = e->tok;
9046 [ + - ][ + - ]: 4075 : sym->name = "__tracepoint_arg_" + arg->name;
[ + - ]
9047 [ + - ]: 4075 : provide (sym);
9048 : : }
9049 : : else
9050 : : {
9051 : : // make a copy of the original as a bare target symbol for the tracepoint
9052 : : // value, which will be passed into the dwarf dereferencing code
9053 [ + - ]: 1199 : target_symbol* e2 = deep_copy_visitor::deep_copy(e);
9054 [ + - ]: 1199 : e2->components.clear();
9055 : :
9056 [ + - ][ + + ]: 1199 : if (e->components.back().type == target_symbol::comp_pretty_print)
9057 : : {
9058 [ - + ]: 864 : if (lvalue)
9059 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot write to pretty-printed variable"), e->tok);
9060 : :
9061 [ + - ]: 864 : dwarf_pretty_print dpp(dw, &arg->type_die, e2, arg->isptr, false, *e);
9062 [ + - ][ + - ]: 864 : dpp.expand()->visit (this);
9063 [ + - ]: 6094 : return;
9064 : : }
9065 : :
9066 : 335 : bool userspace_p = false;
9067 : : string fname = (string(lvalue ? "_tracepoint_tvar_set" : "_tracepoint_tvar_get")
9068 : : + "_" + e->sym_name()
9069 [ - + ][ + - ]: 335 : + "_" + lex_cast(tick++));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
9070 : :
9071 : 335 : exp_type type = pe_long;
9072 [ + + ]: 335 : string code = dw.literal_stmt_for_pointer (&arg->type_die, e, lvalue, type);
9073 : :
9074 : : functioncall* n = synthetic_embedded_deref_call(dw.sess, fname, code, type,
9075 [ + - ]: 291 : userspace_p, lvalue, e, e2);
9076 : :
9077 [ - + ]: 291 : if (lvalue)
9078 : : {
9079 : : // Provide the functioncall to our parent, so that it can be
9080 : : // used to substitute for the assignment node immediately above
9081 : : // us.
9082 [ # # ][ # # ]: 0 : assert(!target_symbol_setter_functioncalls.empty());
9083 [ # # ]: 0 : *(target_symbol_setter_functioncalls.top()) = n;
9084 : : }
9085 : :
9086 : : // Revisit the functioncall so arguments can be expanded.
9087 [ + - ][ + - ]: 4410 : n->visit (this);
[ + - ]
9088 [ + - ][ + + ]: 6073 : }
9089 : : }
9090 : :
9091 : :
9092 : : void
9093 : 2050 : tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
9094 : : {
9095 [ - + ]: 2050 : if (e->addressof)
9096 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot take address of context variable"), e->tok);
9097 : :
9098 [ - + ]: 2050 : if (is_active_lvalue (e))
9099 [ # # ][ # # ]: 0 : throw semantic_error(_F("write to tracepoint '%s' not permitted", e->name.c_str()), e->tok);
[ # # ]
9100 : :
9101 [ + + ]: 2050 : if (e->name == "$$name")
9102 : : {
9103 [ + - ][ + - ]: 682 : e->assert_no_components("tracepoint");
[ + - ]
9104 : :
9105 : : // Synthesize an embedded expression.
9106 [ + - ]: 682 : embedded_expr *expr = new embedded_expr;
9107 : 682 : expr->tok = e->tok;
9108 : : expr->code = string("/* string */ /* pure */ ")
9109 [ + - ][ + - ]: 682 : + string("c->ips.tracepoint_name ? c->ips.tracepoint_name : \"\"");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
9110 : 682 : provide (expr);
9111 : : }
9112 [ + + ][ + - ]: 1368 : else if (e->name == "$$vars" || e->name == "$$parms")
[ + - ]
9113 : : {
9114 [ + - ][ + - ]: 1368 : e->assert_no_components("tracepoint", true);
[ + - ]
9115 : :
9116 [ + - ]: 1368 : token* pf_tok = new token(*e->tok);
9117 : 1368 : pf_tok->content = "sprintf";
9118 : :
9119 : 1368 : print_format* pf = print_format::create(pf_tok);
9120 : :
9121 [ + + ]: 4728 : for (unsigned i = 0; i < args.size(); ++i)
9122 : : {
9123 [ - + ]: 3360 : if (!args[i].usable)
9124 : 0 : continue;
9125 [ + + ]: 3360 : if (i > 0)
9126 [ + - ]: 1992 : pf->raw_components += " ";
9127 [ + - ]: 3360 : pf->raw_components += args[i].name;
9128 [ + - ][ + - ]: 3360 : target_symbol *tsym = new target_symbol;
9129 : 3360 : tsym->tok = e->tok;
9130 [ + - ][ + - ]: 3360 : tsym->name = "$" + args[i].name;
[ + - ]
9131 [ + - ]: 3360 : tsym->components = e->components;
9132 : :
9133 : : // every variable should always be accessible!
9134 : 3360 : tsym->saved_conversion_error = 0;
9135 [ + - ]: 3360 : expression *texp = require<expression> (tsym); // NB: throws nothing ...
9136 [ - + ]: 3360 : if (tsym->saved_conversion_error) // ... but this is how we know it happened.
9137 : : {
9138 [ # # ]: 0 : if (dw.sess.verbose>2)
9139 [ # # ]: 0 : for (const semantic_error *c = tsym->saved_conversion_error;
9140 : : c != 0; c = c->chain)
9141 [ # # ][ # # ]: 0 : clog << _("variable location problem [man error::dwarf]: ") << c->what() << endl;
[ # # ]
9142 [ # # ]: 0 : pf->raw_components += "=?";
9143 : 0 : continue;
9144 : : }
9145 : :
9146 [ + - ]: 4206 : if (!e->components.empty() &&
[ + + + - ]
[ + + ]
9147 : 846 : e->components[0].type == target_symbol::comp_pretty_print)
9148 [ + - ]: 846 : pf->raw_components += "=%s";
9149 : : else
9150 [ + + ][ + - ]: 2514 : pf->raw_components += args[i].isptr ? "=%p" : "=%#x";
9151 [ + - ]: 3360 : pf->args.push_back(texp);
9152 : : }
9153 : :
9154 [ + - ]: 1368 : pf->components = print_format::string_to_components(pf->raw_components);
9155 : 1368 : provide (pf);
9156 : : }
9157 : : else
9158 : 0 : assert(0); // shouldn't get here
9159 : 2050 : }
9160 : :
9161 : : void
9162 : 8123 : tracepoint_var_expanding_visitor::visit_target_symbol (target_symbol* e)
9163 : : {
9164 : : try
9165 : : {
9166 [ + - ][ + - ]: 24369 : assert(e->name.size() > 0
[ + - ][ # # ]
[ # # ]
9167 : : && ((e->name[0] == '$' && e->target_name == "")
9168 [ + - ][ + - ]: 24369 : || (e->name == "@var" && e->target_name != "")));
[ - + ][ # # ]
[ # # ]
9169 : :
9170 [ + - ][ + + ]: 8123 : if (e->name == "$$name" || e->name == "$$parms" || e->name == "$$vars")
[ + - ][ + + ]
[ + - ][ + + ]
[ + + ]
9171 [ + - ]: 2050 : visit_target_symbol_context (e);
9172 [ + - ][ - + ]: 6073 : else if (e->name == "@var")
9173 [ # # ][ # # ]: 0 : throw semantic_error(_("cannot use @var DWARF variables in tracepoints"), e->tok);
9174 : : else
9175 [ + + ]: 6073 : visit_target_symbol_arg (e);
9176 : : }
9177 [ - + ]: 1686 : catch (const semantic_error &er)
9178 : : {
9179 [ - + ]: 843 : e->chain (er);
9180 [ - + ]: 843 : provide (e);
9181 : : }
9182 : 8123 : }
9183 : :
9184 : :
9185 : :
9186 : 1925 : tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s,
9187 : : dwflpp& dw, Dwarf_Die& func_die,
9188 : : const string& tracepoint_name,
9189 : : probe* base, probe_point* loc):
9190 : : derived_probe (base, loc, true /* .components soon rewritten */),
9191 [ + - ][ + - ]: 1925 : sess (s), tracepoint_name (tracepoint_name)
[ + - ]
9192 : : {
9193 : : // create synthetic probe point name; preserve condition
9194 [ + - ]: 1925 : vector<probe_point::component*> comps;
9195 [ + - ][ + - ]: 1925 : comps.push_back (new probe_point::component (TOK_KERNEL));
[ + - ]
9196 [ + - ][ + - ]: 1925 : comps.push_back (new probe_point::component (TOK_TRACE, new literal_string (tracepoint_name)));
[ + - ][ + - ]
[ + - ]
9197 [ + - ][ + - ]: 1925 : this->sole_location()->components = comps;
9198 : :
9199 : : // fill out the available arguments in this tracepoint
9200 [ + - ]: 1925 : build_args(dw, func_die);
9201 : :
9202 : : // determine which header defined this tracepoint
9203 [ + - ][ + - ]: 1925 : string decl_file = dwarf_decl_file(&func_die);
9204 [ + - ]: 1925 : header = decl_file;
9205 : :
9206 : : #if 0 /* This convention is not enforced. */
9207 : : size_t header_pos = decl_file.rfind("trace/");
9208 : : if (header_pos == string::npos)
9209 : : throw semantic_error ("cannot parse header location for tracepoint '"
9210 : : + tracepoint_name + "' in '"
9211 : : + decl_file + "'");
9212 : : header = decl_file.substr(header_pos);
9213 : : #endif
9214 : :
9215 : : // tracepoints from FOO_event_types.h should really be included from FOO.h
9216 : : // XXX can dwarf tell us the include hierarchy? it would be better to
9217 : : // ... walk up to see which one was directly included by tracequery.c
9218 : : // XXX: see also PR9993.
9219 [ + - ]: 1925 : size_t header_pos = header.find("_event_types");
9220 [ - + ]: 1925 : if (header_pos != string::npos)
9221 [ # # ]: 0 : header.erase(header_pos, 12);
9222 : :
9223 : : // Now expand the local variables in the probe body
9224 [ + - ]: 1925 : tracepoint_var_expanding_visitor v (dw, name, args);
9225 [ + - ]: 1925 : v.replace (this->body);
9226 [ + + ]: 6657 : for (unsigned i = 0; i < args.size(); i++)
9227 [ + + ]: 4732 : if (args[i].used)
9228 : : {
9229 [ + - ][ + - ]: 2788 : vardecl* v = new vardecl;
9230 [ + - ][ + - ]: 2788 : v->name = "__tracepoint_arg_" + args[i].name;
[ + - ]
9231 : 2788 : v->tok = this->tok;
9232 [ + - ]: 2788 : v->set_arity(0, this->tok);
9233 : 2788 : v->type = pe_long;
9234 : 2788 : v->synthetic = true;
9235 [ + - ]: 2788 : this->locals.push_back (v);
9236 : : }
9237 : :
9238 [ - + ]: 1925 : if (sess.verbose > 2)
9239 [ # # ][ # # ]: 1925 : clog << "tracepoint-based " << name << " tracepoint='" << tracepoint_name << "'" << endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ][ + - ]
[ + - ]
9240 : 1925 : }
9241 : :
9242 : :
9243 : : static bool
9244 : 5654 : resolve_tracepoint_arg_type(tracepoint_arg& arg)
9245 : : {
9246 : : Dwarf_Die type;
9247 [ + - ][ + + : 5654 : switch (dwarf_tag(&arg.type_die))
+ - - ]
9248 : : {
9249 : : case DW_TAG_typedef:
9250 : : case DW_TAG_const_type:
9251 : : case DW_TAG_volatile_type:
9252 : : // iterate on the referent type
9253 [ + - ]: 922 : return (dwarf_attr_die(&arg.type_die, DW_AT_type, &arg.type_die)
9254 [ + - ][ + - ]: 922 : && resolve_tracepoint_arg_type(arg));
[ + - ]
9255 : : case DW_TAG_base_type:
9256 : : case DW_TAG_enumeration_type:
9257 : : // base types will simply be treated as script longs
9258 : 2347 : arg.isptr = false;
9259 : 2347 : return true;
9260 : : case DW_TAG_pointer_type:
9261 : : // pointers can be treated as script longs,
9262 : : // and if we know their type, they can also be dereferenced
9263 : 2385 : type = arg.type_die;
9264 [ + - ][ + + ]: 2785 : while (dwarf_attr_die(&arg.type_die, DW_AT_type, &arg.type_die))
9265 : : {
9266 : : // It still might be a non-type, e.g. const void,
9267 : : // so we need to strip away all qualifiers.
9268 [ + - ]: 2712 : int tag = dwarf_tag(&arg.type_die);
9269 [ + + ][ + + ]: 2712 : if (tag != DW_TAG_typedef &&
[ + - ]
9270 : : tag != DW_TAG_const_type &&
9271 : : tag != DW_TAG_volatile_type)
9272 : : {
9273 : 2312 : arg.isptr = true;
9274 : 2312 : break;
9275 : : }
9276 : : }
9277 [ + + ]: 2385 : if (!arg.isptr)
9278 : 73 : arg.type_die = type;
9279 [ + - ]: 2385 : arg.typecast = "(intptr_t)";
9280 : 2385 : return true;
9281 : : case DW_TAG_structure_type:
9282 : : case DW_TAG_union_type:
9283 : : // for structs/unions which are passed by value, we turn it into
9284 : : // a pointer that can be dereferenced.
9285 : 0 : arg.isptr = true;
9286 [ # # ]: 0 : arg.typecast = "(intptr_t)&";
9287 : 0 : return true;
9288 : : default:
9289 : : // should we consider other types too?
9290 : 5654 : return false;
9291 : : }
9292 : : }
9293 : :
9294 : :
9295 : : void
9296 : 1925 : tracepoint_derived_probe::build_args(dwflpp&, Dwarf_Die& func_die)
9297 : : {
9298 : : Dwarf_Die arg;
9299 [ + - ][ + - ]: 1925 : if (dwarf_child(&func_die, &arg) == 0)
9300 [ + + ]: 4732 : do
9301 [ + - ][ + - ]: 4732 : if (dwarf_tag(&arg) == DW_TAG_formal_parameter)
9302 : : {
9303 : : // build a tracepoint_arg for this parameter
9304 [ + - ]: 4732 : tracepoint_arg tparg;
9305 [ + - ][ + - ]: 4732 : tparg.name = dwarf_diename(&arg);
9306 : :
9307 : : // read the type of this parameter
9308 [ + - ][ + - ]: 9464 : if (!dwarf_attr_die (&arg, DW_AT_type, &tparg.type_die)
[ - + ][ - + ]
9309 [ + - ]: 4732 : || !dwarf_type_name(&tparg.type_die, tparg.c_type))
9310 : 0 : throw semantic_error (_F("cannot get type of parameter '%s' of tracepoint '%s'",
9311 [ # # ][ # # ]: 0 : tparg.name.c_str(), tracepoint_name.c_str()));
[ # # ][ # # ]
9312 : :
9313 [ + - ]: 4732 : tparg.usable = resolve_tracepoint_arg_type(tparg);
9314 [ + - ]: 4732 : args.push_back(tparg);
9315 [ - + ]: 4732 : if (sess.verbose > 4)
9316 [ # # ][ # # ]: 0 : clog << _F("found parameter for tracepoint '%s': type:'%s' name:'%s' %s",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
9317 : : tracepoint_name.c_str(), tparg.c_type.c_str(), tparg.name.c_str(),
9318 [ # # ][ + - ]: 4732 : tparg.usable ? "ok" : "unavailable") << endl;
9319 : : }
9320 [ + - ]: 4732 : while (dwarf_siblingof(&arg, &arg) == 0);
9321 : 1925 : }
9322 : :
9323 : : void
9324 : 0 : tracepoint_derived_probe::getargs(std::list<std::string> &arg_set) const
9325 : : {
9326 [ # # ]: 0 : for (unsigned i = 0; i < args.size(); ++i)
9327 [ # # ]: 0 : if (args[i].usable)
9328 [ # # ][ # # ]: 0 : arg_set.push_back("$"+args[i].name+":"+args[i].c_type);
[ # # ][ # # ]
[ # # ]
9329 : 0 : }
9330 : :
9331 : : void
9332 : 1925 : tracepoint_derived_probe::join_group (systemtap_session& s)
9333 : : {
9334 [ + + ]: 1925 : if (! s.tracepoint_derived_probes)
9335 [ + - ]: 77 : s.tracepoint_derived_probes = new tracepoint_derived_probe_group ();
9336 : 1925 : s.tracepoint_derived_probes->enroll (this);
9337 : 1925 : }
9338 : :
9339 : :
9340 : : void
9341 : 1712 : tracepoint_derived_probe::print_dupe_stamp(ostream& o)
9342 : : {
9343 [ + + ]: 5862 : for (unsigned i = 0; i < args.size(); i++)
9344 [ + + ]: 4150 : if (args[i].used)
9345 : 3750 : o << "__tracepoint_arg_" << args[i].name << endl;
9346 : 1712 : }
9347 : :
9348 : :
9349 : 160 : static vector<string> tracepoint_extra_decls (systemtap_session& s, const string& header)
9350 : : {
9351 : 160 : vector<string> they_live;
9352 : : // PR 9993
9353 : : // XXX: may need this to be configurable
9354 [ + - ][ + - ]: 160 : they_live.push_back ("#include <linux/skbuff.h>");
[ + - ]
9355 : :
9356 : : // PR11649: conditional extra header
9357 : : // for kvm tracepoints in 2.6.33ish
9358 [ + - ][ + - ]: 160 : if (s.kernel_config["CONFIG_KVM"] != string("")) {
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
9359 [ # # ][ # # ]: 0 : they_live.push_back ("#include <linux/kvm_host.h>");
[ # # ]
9360 : : }
9361 : :
9362 [ + - ][ + + ]: 160 : if (header.find("xfs") != string::npos && s.kernel_config["CONFIG_XFS_FS"] != string("")) {
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + + ]
[ + - ][ + + ]
[ + + ][ + - ]
[ + + ][ - +
# # # # #
# # # ]
9363 [ # # ][ # # ]: 0 : they_live.push_back ("#define XFS_BIG_BLKNOS 1");
[ # # ]
9364 [ # # ][ # # ]: 0 : if (s.kernel_source_tree != "")
9365 [ # # ][ # # ]: 0 : they_live.push_back ("#include \"fs/xfs/xfs_types.h\""); // in kernel-source tree
[ # # ]
9366 [ # # ][ # # ]: 0 : they_live.push_back ("struct xfs_mount;");
[ # # ]
9367 [ # # ][ # # ]: 0 : they_live.push_back ("struct xfs_inode;");
[ # # ]
9368 [ # # ][ # # ]: 0 : they_live.push_back ("struct xfs_buf;");
[ # # ]
9369 [ # # ][ # # ]: 0 : they_live.push_back ("struct xfs_bmbt_irec;");
[ # # ]
9370 [ # # ][ # # ]: 0 : they_live.push_back ("struct xfs_trans;");
[ # # ]
9371 : : }
9372 : :
9373 [ + - ][ - + ]: 160 : if (header.find("nfs") != string::npos && s.kernel_config["CONFIG_NFSD"] != string("")) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ - + ]
[ # # ][ - + ]
[ - + ][ # # ]
[ - + ][ - +
# # # # #
# # # ]
9374 [ # # ][ # # ]: 0 : they_live.push_back ("struct rpc_task;");
[ # # ]
9375 : : }
9376 : : // RHEL6.3
9377 [ + - ][ + + ]: 160 : if (header.find("rpc") != string::npos && s.kernel_config["CONFIG_NFSD"] != string("")) {
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + + ]
[ + - ][ + + ]
[ + + ][ + - ]
[ + + ][ - +
# # # # #
# # # ]
9378 [ # # ][ # # ]: 0 : they_live.push_back ("struct rpc_clnt;");
[ # # ]
9379 [ # # ][ # # ]: 0 : they_live.push_back ("struct rpc_wait_queue;");
[ # # ]
9380 : : }
9381 : :
9382 [ + - ][ + - ]: 160 : they_live.push_back ("#include <asm/cputime.h>");
[ + - ]
9383 : :
9384 : : // linux 3.0
9385 [ + - ][ + - ]: 160 : they_live.push_back ("struct cpu_workqueue_struct;");
[ + - ]
9386 : :
9387 [ + - ][ + + ]: 160 : if (header.find("ext4") != string::npos && s.kernel_config["CONFIG_EXT4_FS"] != string(""))
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + + ][ + - ]
[ + + ][ + +
# # # # #
# # # ]
9388 [ + - ][ + - ]: 3 : if (s.kernel_source_tree != "")
9389 [ + - ][ + - ]: 3 : they_live.push_back ("#include \"fs/ext4/ext4.h\""); // in kernel-source tree
[ + - ]
9390 : :
9391 [ + - ][ + + ]: 160 : if (header.find("ext3") != string::npos && s.kernel_config["CONFIG_EXT3_FS"] != string(""))
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + + ][ + - ]
[ + + ][ + +
# # # # #
# # # ]
9392 [ + - ][ + - ]: 1 : they_live.push_back ("struct ext3_reserve_window_node;");
[ + - ]
9393 : :
9394 : 160 : return they_live;
9395 : : }
9396 : :
9397 : :
9398 : : void
9399 : 40 : tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s)
9400 : : {
9401 [ + - ][ + - ]: 40 : if (probes.empty())
9402 : 40 : return;
9403 : :
9404 [ + - ][ + - ]: 40 : s.op->newline() << "/* ---- tracepoint probes ---- */";
9405 [ + - ]: 40 : s.op->newline();
9406 : :
9407 : :
9408 : : // We create a MODULE_aux_N.c file for each tracepoint header, to allow them
9409 : : // to be separately compiled. That's because kernel tracepoint headers sometimes
9410 : : // conflict. PR13155.
9411 : :
9412 [ + - ]: 40 : map<string,translator_output*> per_header_aux;
9413 : : // GC NB: the translator_output* structs are owned/retained by the systemtap_session.
9414 : :
9415 [ + + ]: 896 : for (unsigned i = 0; i < probes.size(); ++i)
9416 : : {
9417 : 856 : tracepoint_derived_probe *p = probes[i];
9418 [ + - ]: 856 : string header = p->header;
9419 : :
9420 : : // We cache the auxiliary output files on a per-header basis. We don't
9421 : : // need one aux file per tracepoint, only one per tracepoint-header.
9422 [ + - ]: 856 : translator_output *tpop = per_header_aux[header];
9423 [ + + ]: 856 : if (tpop == 0)
9424 : : {
9425 [ + - ]: 110 : tpop = s.op_create_auxiliary();
9426 [ + - ]: 110 : per_header_aux[header] = tpop;
9427 : :
9428 : : // PR9993: Add extra headers to work around undeclared types in individual
9429 : : // include/trace/foo.h files
9430 [ + - ]: 110 : const vector<string>& extra_decls = tracepoint_extra_decls (s, header);
9431 [ + + ]: 442 : for (unsigned z=0; z<extra_decls.size(); z++)
9432 [ + - ][ + - ]: 332 : tpop->newline() << extra_decls[z] << "\n";
[ + - ]
9433 : :
9434 : : // strip include/ substring, the same way as done in get_tracequery_module()
9435 [ + - ]: 110 : size_t root_pos = header.rfind("include/");
9436 [ + - ][ + - ]: 110 : header = ((root_pos != string::npos) ? header.substr(root_pos + 8) : header);
[ # # ][ + - ]
[ + - ]
9437 : :
9438 [ + - ][ + - ]: 110 : tpop->newline() << "#include <linux/tracepoint.h>" << endl;
[ + - ]
9439 [ + - ][ + - ]: 110 : tpop->newline() << "#include <" << header << ">";
[ + - ][ + - ]
9440 : :
9441 : : // Starting in 2.6.35, at the same time NOARGS was added, the callback
9442 : : // always has a void* as the first parameter. PR11599
9443 [ + - ][ + - ]: 110 : tpop->newline() << "#ifdef DECLARE_TRACE_NOARGS";
9444 [ + - ][ + - ]: 110 : tpop->newline() << "#define STAP_TP_DATA , NULL";
9445 [ + - ][ + - ]: 110 : tpop->newline() << "#define STAP_TP_PROTO void *cb_data"
9446 [ + - ]: 110 : << " __attribute__ ((unused))";
9447 [ + - ][ + - ]: 110 : if (!p->args.empty())
9448 [ + - ][ + - ]: 110 : tpop->line() << ",";
9449 [ + - ][ + - ]: 110 : tpop->newline() << "#else";
9450 [ + - ][ + - ]: 110 : tpop->newline() << "#define STAP_TP_DATA";
9451 [ + - ][ + - ]: 110 : tpop->newline() << "#define STAP_TP_PROTO";
9452 [ + - ][ - + ]: 110 : if (p->args.empty())
9453 [ # # ][ # # ]: 0 : tpop->line() << " void";
9454 [ + - ][ + - ]: 110 : tpop->newline() << "#endif";
9455 : :
9456 [ + - ][ + - ]: 110 : tpop->newline() << "#define intptr_t long";
[ + - ]
9457 : : }
9458 : :
9459 : : // collect the args that are actually in use
9460 [ + - ]: 856 : vector<const tracepoint_arg*> used_args;
9461 [ + + ]: 2931 : for (unsigned j = 0; j < p->args.size(); ++j)
9462 [ + + ]: 2075 : if (p->args[j].used)
9463 [ + - ]: 1875 : used_args.push_back(&p->args[j]);
9464 : :
9465 : : // forward-declare the generated-side tracepoint callback
9466 [ + - ][ + - ]: 856 : tpop->newline() << "void enter_real_tracepoint_probe_" << i << "(";
[ + - ][ + - ]
9467 [ + - ]: 856 : tpop->indent(2);
9468 [ + - ][ + + ]: 856 : if (used_args.empty())
9469 [ + - ][ + - ]: 82 : tpop->line() << "void";
9470 [ + + ]: 2731 : for (unsigned j = 0; j < used_args.size(); ++j)
9471 : : {
9472 [ + + ]: 1875 : if (j > 0)
9473 [ + - ][ + - ]: 1101 : tpop->line() << ", ";
9474 [ + - ][ + - ]: 1875 : tpop->line() << "int64_t";
9475 : : }
9476 [ + - ][ + - ]: 856 : tpop->line() << ");";
9477 [ + - ]: 856 : tpop->indent(-2);
9478 : :
9479 : : // define the generated-side tracepoint callback - in the main translator-output
9480 [ + - ][ + - ]: 856 : s.op->newline() << "void enter_real_tracepoint_probe_" << i << "(";
[ + - ][ + - ]
9481 [ + - ]: 856 : s.op->indent(2);
9482 [ + - ][ + + ]: 856 : if (used_args.empty())
9483 [ + - ][ + - ]: 82 : s.op->newline() << "void";
9484 [ + + ]: 2731 : for (unsigned j = 0; j < used_args.size(); ++j)
9485 : : {
9486 [ + + ]: 1875 : if (j > 0)
9487 [ + - ][ + - ]: 1101 : s.op->line() << ", ";
9488 [ + - ][ + - ]: 1875 : s.op->newline() << "int64_t __tracepoint_arg_" << used_args[j]->name;
[ + - ]
9489 : : }
9490 [ + - ][ + - ]: 856 : s.op->newline() << ")";
9491 [ + - ][ + - ]: 856 : s.op->newline(-2) << "{";
9492 [ + - ][ + - ]: 856 : s.op->newline(1) << "const struct stap_probe * const probe = "
9493 [ + - ][ + - ]: 856 : << common_probe_init (p) << ";";
[ + - ][ + - ]
9494 : : common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "probe",
9495 [ + - ][ + - ]: 856 : "stp_probe_type_tracepoint");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
9496 [ + - ][ + - ]: 856 : s.op->newline() << "c->ips.tracepoint_name = "
9497 [ + - ][ + - ]: 1712 : << lex_cast_qstring (p->tracepoint_name)
[ + - ]
9498 [ + - ]: 856 : << ";";
9499 [ + + ]: 2731 : for (unsigned j = 0; j < used_args.size(); ++j)
9500 : : {
9501 [ + - ][ + - ]: 1875 : s.op->newline() << "c->probe_locals." << p->name
[ + - ]
9502 [ + - ][ + - ]: 3750 : << "." + s.up->c_localname("__tracepoint_arg_" + used_args[j]->name)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
9503 [ + - ][ + - ]: 1875 : << " = __tracepoint_arg_" << used_args[j]->name << ";";
[ + - ]
9504 : : }
9505 [ + - ][ + - ]: 856 : s.op->newline() << "(*probe->ph) (c);";
9506 [ + - ]: 856 : common_probe_entryfn_epilogue (s, true);
9507 [ + - ][ + - ]: 856 : s.op->newline(-1) << "}";
9508 : :
9509 : : // define the real tracepoint callback function
9510 [ + - ][ + - ]: 856 : tpop->newline() << "static void enter_tracepoint_probe_" << i << "(";
[ + - ][ + - ]
9511 [ + - ][ + - ]: 856 : tpop->newline(2) << "STAP_TP_PROTO";
9512 [ + + ]: 2931 : for (unsigned j = 0; j < p->args.size(); ++j)
9513 : : {
9514 [ + + ]: 2075 : if (j > 0)
9515 [ + - ][ + - ]: 1219 : tpop->line() << ", ";
9516 [ + - ][ + - ]: 2075 : tpop->newline() << p->args[j].c_type << " __tracepoint_arg_" << p->args[j].name;
[ + - ][ + - ]
9517 : : }
9518 [ + - ][ + - ]: 856 : tpop->newline() << ")";
9519 [ + - ][ + - ]: 856 : tpop->newline(-2) << "{";
9520 [ + - ][ + - ]: 856 : tpop->newline(1) << "enter_real_tracepoint_probe_" << i << "(";
[ + - ][ + - ]
9521 [ + - ]: 856 : tpop->indent(2);
9522 [ + + ]: 2731 : for (unsigned j = 0; j < used_args.size(); ++j)
9523 : : {
9524 [ + + ]: 1875 : if (j > 0)
9525 [ + - ][ + - ]: 1101 : tpop->line() << ", ";
9526 [ + - ][ + - ]: 1875 : tpop->newline() << "(int64_t)" << used_args[j]->typecast
[ + - ]
9527 [ + - ][ + - ]: 1875 : << "__tracepoint_arg_" << used_args[j]->name;
9528 : : }
9529 [ + - ][ + - ]: 856 : tpop->newline() << ");";
9530 [ + - ][ + - ]: 856 : tpop->newline(-3) << "}";
9531 : :
9532 : :
9533 : : // emit normalized registration functions
9534 [ + - ][ + - ]: 856 : tpop->newline() << "int register_tracepoint_probe_" << i << "(void) {";
[ + - ][ + - ]
9535 [ + - ][ + - ]: 856 : tpop->newline(1) << "return register_trace_" << p->tracepoint_name
[ + - ]
9536 [ + - ][ + - ]: 856 : << "(enter_tracepoint_probe_" << i << " STAP_TP_DATA);";
[ + - ]
9537 [ + - ][ + - ]: 856 : tpop->newline(-1) << "}";
9538 : :
9539 : : // NB: we're not prepared to deal with unreg failures. However, failures
9540 : : // can only occur if the tracepoint doesn't exist (yet?), or if we
9541 : : // weren't even registered. The former should be OKed by the initial
9542 : : // registration call, and the latter is safe to ignore.
9543 [ + - ][ + - ]: 856 : tpop->newline() << "void unregister_tracepoint_probe_" << i << "(void) {";
[ + - ][ + - ]
9544 [ + - ][ + - ]: 856 : tpop->newline(1) << "(void) unregister_trace_" << p->tracepoint_name
[ + - ]
9545 [ + - ][ + - ]: 856 : << "(enter_tracepoint_probe_" << i << " STAP_TP_DATA);";
[ + - ]
9546 [ + - ][ + - ]: 856 : tpop->newline(-1) << "}";
9547 [ + - ]: 856 : tpop->newline();
9548 : :
9549 : : // declare normalized registration functions
9550 [ + - ][ + - ]: 856 : s.op->newline() << "int register_tracepoint_probe_" << i << "(void);";
[ + - ][ + - ]
9551 [ + - ][ + - ]: 856 : s.op->newline() << "void unregister_tracepoint_probe_" << i << "(void);";
[ + - ][ + - ]
9552 : :
9553 [ + - ]: 856 : tpop->assert_0_indent();
9554 [ + - ][ + - ]: 856 : }
9555 : :
9556 : : // emit an array of registration functions for easy init/shutdown
9557 [ + - ][ + - ]: 40 : s.op->newline() << "static struct stap_tracepoint_probe {";
9558 [ + - ][ + - ]: 40 : s.op->newline(1) << "int (*reg)(void);";
9559 [ + - ][ + - ]: 40 : s.op->newline(0) << "void (*unreg)(void);";
9560 [ + - ][ + - ]: 40 : s.op->newline(-1) << "} stap_tracepoint_probes[] = {";
9561 [ + - ]: 40 : s.op->indent(1);
9562 [ + + ]: 896 : for (unsigned i = 0; i < probes.size(); ++i)
9563 : : {
9564 [ + - ][ + - ]: 856 : s.op->newline () << "{";
9565 [ + - ][ + - ]: 856 : s.op->line() << " .reg=®ister_tracepoint_probe_" << i << ",";
[ + - ][ + - ]
9566 [ + - ][ + - ]: 856 : s.op->line() << " .unreg=&unregister_tracepoint_probe_" << i;
[ + - ]
9567 [ + - ][ + - ]: 856 : s.op->line() << " },";
9568 : : }
9569 [ + - ][ + - ]: 40 : s.op->newline(-1) << "};";
9570 [ + - ][ + - ]: 40 : s.op->newline();
9571 : : }
9572 : :
9573 : :
9574 : : void
9575 : 40 : tracepoint_derived_probe_group::emit_module_init (systemtap_session &s)
9576 : : {
9577 [ - + ]: 40 : if (probes.size () == 0)
9578 : 40 : return;
9579 : :
9580 : 40 : s.op->newline() << "/* init tracepoint probes */";
9581 : 40 : s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
9582 : 40 : s.op->newline(1) << "rc = stap_tracepoint_probes[i].reg();";
9583 : 40 : s.op->newline() << "if (rc) {";
9584 : 40 : s.op->newline(1) << "for (j=i-1; j>=0; j--)"; // partial rollback
9585 : 40 : s.op->newline(1) << "stap_tracepoint_probes[j].unreg();";
9586 : 40 : s.op->newline(-1) << "break;"; // don't attempt to register any more probes
9587 : 40 : s.op->newline(-1) << "}";
9588 : 40 : s.op->newline(-1) << "}";
9589 : :
9590 : : // This would be technically proper (on those autoconf-detectable
9591 : : // kernels that include this function in tracepoint.h), however we
9592 : : // already make several calls to synchronze_sched() during our
9593 : : // shutdown processes.
9594 : :
9595 : : // s.op->newline() << "if (rc)";
9596 : : // s.op->newline(1) << "tracepoint_synchronize_unregister();";
9597 : : // s.op->indent(-1);
9598 : : }
9599 : :
9600 : :
9601 : : void
9602 : 50 : tracepoint_derived_probe_group::emit_module_exit (systemtap_session& s)
9603 : : {
9604 [ - + ]: 50 : if (probes.empty())
9605 : 50 : return;
9606 : :
9607 : 50 : s.op->newline() << "/* deregister tracepoint probes */";
9608 : 50 : s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
9609 : 50 : s.op->newline(1) << "stap_tracepoint_probes[i].unreg();";
9610 : 50 : s.op->indent(-1);
9611 : :
9612 : : // Not necessary: see above.
9613 : :
9614 : : // s.op->newline() << "tracepoint_synchronize_unregister();";
9615 : : }
9616 : :
9617 : :
9618 [ + - ][ - + ]: 592 : struct tracepoint_query : public base_query
9619 : : {
9620 : 592 : tracepoint_query(dwflpp & dw, const string & tracepoint,
9621 : : probe * base_probe, probe_point * base_loc,
9622 : : vector<derived_probe *> & results):
9623 : : base_query(dw, "*"), tracepoint(tracepoint),
9624 : : base_probe(base_probe), base_loc(base_loc),
9625 [ + - ][ + - ]: 592 : results(results) {}
[ + - ][ + - ]
9626 : :
9627 : : const string& tracepoint;
9628 : :
9629 : : probe * base_probe;
9630 : : probe_point * base_loc;
9631 : : vector<derived_probe *> & results;
9632 : : set<string> probed_names;
9633 : :
9634 : : void handle_query_module();
9635 : : int handle_query_cu(Dwarf_Die * cudie);
9636 : : int handle_query_func(Dwarf_Die * func);
9637 : 0 : void query_library (const char *) {}
9638 : 0 : void query_plt (const char *entry, size_t addr) {}
9639 : :
9640 : : static int tracepoint_query_cu (Dwarf_Die * cudie, void * arg);
9641 : : static int tracepoint_query_func (Dwarf_Die * func, base_query * query);
9642 : : };
9643 : :
9644 : :
9645 : : void
9646 : 23088 : tracepoint_query::handle_query_module()
9647 : : {
9648 : : // look for the tracepoints in each CU
9649 : 23088 : dw.iterate_over_cus(tracepoint_query_cu, this, false);
9650 : 23088 : }
9651 : :
9652 : :
9653 : : int
9654 : 23088 : tracepoint_query::handle_query_cu(Dwarf_Die * cudie)
9655 : : {
9656 [ + - ]: 23088 : dw.focus_on_cu (cudie);
9657 : :
9658 : : // look at each function to see if it's a tracepoint
9659 [ + - ]: 23088 : string function = "stapprobe_" + tracepoint;
9660 [ + - ][ + - ]: 23088 : return dw.iterate_over_functions (tracepoint_query_func, this, function);
9661 : : }
9662 : :
9663 : :
9664 : : int
9665 : 1925 : tracepoint_query::handle_query_func(Dwarf_Die * func)
9666 : : {
9667 [ + - ]: 1925 : dw.focus_on_function (func);
9668 : :
9669 [ + - ][ - + ]: 1925 : assert(startswith(dw.function_name, "stapprobe_"));
9670 [ + - ]: 1925 : string tracepoint_instance = dw.function_name.substr(10);
9671 : :
9672 : : // check for duplicates -- sometimes tracepoint headers may be indirectly
9673 : : // included in more than one of our tracequery modules.
9674 [ + - ][ - + ]: 1925 : if (!probed_names.insert(tracepoint_instance).second)
9675 : 0 : return DWARF_CB_OK;
9676 : :
9677 : : derived_probe *dp = new tracepoint_derived_probe (dw.sess, dw, *func,
9678 : : tracepoint_instance,
9679 [ + - ][ + - ]: 1925 : base_probe, base_loc);
9680 [ + - ]: 1925 : results.push_back (dp);
9681 [ + - ]: 1925 : return DWARF_CB_OK;
9682 : : }
9683 : :
9684 : :
9685 : : int
9686 : 23088 : tracepoint_query::tracepoint_query_cu (Dwarf_Die * cudie, void * arg)
9687 : : {
9688 : 23088 : tracepoint_query * q = static_cast<tracepoint_query *>(arg);
9689 [ - + ]: 23088 : if (pending_interrupts) return DWARF_CB_ABORT;
9690 : 23088 : return q->handle_query_cu(cudie);
9691 : : }
9692 : :
9693 : :
9694 : : int
9695 : 1925 : tracepoint_query::tracepoint_query_func (Dwarf_Die * func, base_query * query)
9696 : : {
9697 : 1925 : tracepoint_query * q = static_cast<tracepoint_query *>(query);
9698 [ - + ]: 1925 : if (pending_interrupts) return DWARF_CB_ABORT;
9699 : 1925 : return q->handle_query_func(func);
9700 : : }
9701 : :
9702 : :
9703 : : struct tracepoint_builder: public derived_probe_builder
9704 : : {
9705 : : private:
9706 : : dwflpp *dw;
9707 : : bool init_dw(systemtap_session& s);
9708 : : void get_tracequery_modules(systemtap_session& s,
9709 : : const vector<string>& headers,
9710 : : vector<string>& modules);
9711 : :
9712 : : public:
9713 : :
9714 : 1218 : tracepoint_builder(): dw(0) {}
9715 [ # # ][ # # ]: 0 : ~tracepoint_builder() { delete dw; }
[ # # ]
9716 : :
9717 : 1218 : void build_no_more (systemtap_session& s)
9718 : : {
9719 [ + + ][ - + ]: 1218 : if (dw && s.verbose > 3)
9720 : 0 : clog << _("tracepoint_builder releasing dwflpp") << endl;
9721 [ + + ]: 1218 : delete dw;
9722 : 1218 : dw = NULL;
9723 : :
9724 : 1218 : delete_session_module_cache (s);
9725 : 1218 : }
9726 : :
9727 : : void build(systemtap_session& s,
9728 : : probe *base, probe_point *location,
9729 : : literal_map_t const& parameters,
9730 : : vector<derived_probe*>& finished_results);
9731 : : };
9732 : :
9733 : :
9734 : :
9735 : : // Create (or cache) one or more tracequery .o modules, based upon the
9736 : : // tracepoint-related header files given. Return the generated or cached
9737 : : // modules[].
9738 : :
9739 : : void
9740 : 84 : tracepoint_builder::get_tracequery_modules(systemtap_session& s,
9741 : : const vector<string>& headers,
9742 : : vector<string>& modules)
9743 : : {
9744 [ - + ]: 84 : if (s.verbose > 2)
9745 : : {
9746 [ # # ][ # # ]: 0 : clog << _F("Pass 2: getting a tracepoint query for %zu headers: ", headers.size()) << endl;
[ # # ][ # # ]
9747 [ # # ]: 0 : for (size_t i = 0; i < headers.size(); ++i)
9748 [ # # ][ # # ]: 0 : clog << " " << headers[i] << endl;
[ # # ]
9749 : : }
9750 : :
9751 [ + - ]: 84 : map<string,string> headers_cache_obj; // header name -> cache/.../tracequery_hash.o file name
9752 : : // Map the headers to cache .o names. Note that this has side-effects of
9753 : : // creating the $SYSTEMTAP_DIR/.cache/XX/... directory and the hash-log file,
9754 : : // so we prefer not to repeat this.
9755 [ + - ]: 84 : vector<string> uncached_headers;
9756 [ + + ]: 4284 : for (size_t i=0; i<headers.size(); i++)
9757 [ + - ][ + - ]: 4200 : headers_cache_obj[headers[i]] = find_tracequery_hash(s, headers[i]);
[ + - ][ + - ]
9758 : :
9759 : : // They may be in the cache already.
9760 [ + - ][ + - ]: 84 : if (s.use_cache && !s.poison_cache)
9761 [ + + ]: 4284 : for (size_t i=0; i<headers.size(); i++)
9762 : : {
9763 : : // see if the cached module exists
9764 [ + - ]: 4200 : const string& tracequery_path = headers_cache_obj[headers[i]];
9765 [ + - ][ + - ]: 4200 : if (!tracequery_path.empty() && file_exists(tracequery_path))
[ + - ][ + + ]
[ + + ]
9766 : : {
9767 [ - + ]: 4150 : if (s.verbose > 2)
9768 [ # # ][ # # ]: 0 : clog << _F("Pass 2: using cached %s", tracequery_path.c_str()) << endl;
[ # # ][ # # ]
[ # # ]
9769 : :
9770 : : // an empty file is a cached failure
9771 [ + - ][ + + ]: 4150 : if (get_file_size(tracequery_path) > 0)
9772 [ + - ]: 3237 : modules.push_back (tracequery_path);
9773 : : }
9774 : : else
9775 [ + - ]: 50 : uncached_headers.push_back(headers[i]);
9776 : 84 : }
9777 : : else
9778 [ # # ]: 0 : uncached_headers = headers;
9779 : :
9780 : : // If we have nothing left to search for, quit
9781 [ + - ][ + + ]: 168 : if (uncached_headers.empty()) return;
9782 : :
9783 [ + - ]: 1 : map<string,string> headers_tracequery_src; // header -> C-source code mapping
9784 : :
9785 : : // We could query several subsets of headers[] to make this go
9786 : : // faster, but let's KISS and do one at a time.
9787 [ + + ]: 51 : for (size_t i=0; i<uncached_headers.size(); i++)
9788 : : {
9789 : 50 : const string& header = uncached_headers[i];
9790 : :
9791 : : // create a tracequery source file
9792 [ + - ]: 50 : ostringstream osrc;
9793 : :
9794 : : // PR9993: Add extra headers to work around undeclared types in individual
9795 : : // include/trace/foo.h files
9796 [ + - ]: 50 : vector<string> short_decls = tracepoint_extra_decls(s, header);
9797 : :
9798 : : // add each requested tracepoint header
9799 [ + - ]: 50 : size_t root_pos = header.rfind("include/");
9800 : : short_decls.push_back(string("#include <") +
9801 : : ((root_pos != string::npos) ? header.substr(root_pos + 8) : header) +
9802 [ + - ][ + + ]: 50 : string(">"));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
9803 : :
9804 [ + - ][ + - ]: 50 : osrc << "#ifdef CONFIG_TRACEPOINTS" << endl;
9805 [ + - ][ + - ]: 50 : osrc << "#include <linux/tracepoint.h>" << endl;
9806 : :
9807 : : // the kernel has changed this naming a few times, previously TPPROTO,
9808 : : // TP_PROTO, TPARGS, TP_ARGS, etc. so let's just dupe the latest.
9809 [ + - ][ + - ]: 50 : osrc << "#ifndef PARAMS" << endl;
9810 [ + - ][ + - ]: 50 : osrc << "#define PARAMS(args...) args" << endl;
9811 [ + - ][ + - ]: 50 : osrc << "#endif" << endl;
9812 : :
9813 : : // override DECLARE_TRACE to synthesize probe functions for us
9814 [ + - ][ + - ]: 50 : osrc << "#undef DECLARE_TRACE" << endl;
9815 [ + - ][ + - ]: 50 : osrc << "#define DECLARE_TRACE(name, proto, args) \\" << endl;
9816 [ + - ][ + - ]: 50 : osrc << " void stapprobe_##name(proto) {}" << endl;
9817 : :
9818 : : // 2.6.35 added the NOARGS variant, but it's the same for us
9819 [ + - ][ + - ]: 50 : osrc << "#undef DECLARE_TRACE_NOARGS" << endl;
9820 [ + - ][ + - ]: 50 : osrc << "#define DECLARE_TRACE_NOARGS(name) \\" << endl;
9821 [ + - ][ + - ]: 50 : osrc << " DECLARE_TRACE(name, void, )" << endl;
9822 : :
9823 : : // 2.6.38 added the CONDITION variant, which can also just redirect
9824 [ + - ][ + - ]: 50 : osrc << "#undef DECLARE_TRACE_CONDITION" << endl;
9825 [ + - ][ + - ]: 50 : osrc << "#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \\" << endl;
9826 [ + - ][ + - ]: 50 : osrc << " DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))" << endl;
9827 : :
9828 : : // older tracepoints used DEFINE_TRACE, so redirect that too
9829 [ + - ][ + - ]: 50 : osrc << "#undef DEFINE_TRACE" << endl;
9830 [ + - ][ + - ]: 50 : osrc << "#define DEFINE_TRACE(name, proto, args) \\" << endl;
9831 [ + - ][ + - ]: 50 : osrc << " DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))" << endl;
9832 : :
9833 : : // add the specified decls/#includes
9834 [ + + ]: 252 : for (unsigned z=0; z<short_decls.size(); z++)
9835 [ + - ]: 202 : osrc << "#undef TRACE_INCLUDE_FILE\n"
9836 [ + - ]: 202 : << "#undef TRACE_INCLUDE_PATH\n"
9837 [ + - ][ + - ]: 202 : << short_decls[z] << "\n";
9838 : :
9839 : : // finish up the module source
9840 [ + - ][ + - ]: 50 : osrc << "#endif /* CONFIG_TRACEPOINTS */" << endl;
9841 : :
9842 : : // save the source file away
9843 [ + - ][ + - ]: 50 : headers_tracequery_src[header] = osrc.str();
[ + - ][ + - ]
9844 [ + - ][ + - ]: 50 : }
9845 : :
9846 : : // now build them all together
9847 [ + - ]: 1 : map<string,string> tracequery_objs = make_tracequeries(s, headers_tracequery_src);
9848 : :
9849 : : // now plop them into the cache
9850 [ + - ]: 1 : if (s.use_cache)
9851 [ + + ]: 51 : for (size_t i=0; i<uncached_headers.size(); i++)
9852 : : {
9853 : 50 : const string& header = uncached_headers[i];
9854 [ + - ]: 50 : const string& tracequery_obj = tracequery_objs[header];
9855 [ + - ]: 50 : const string& tracequery_path = headers_cache_obj[header];
9856 [ + - ][ + - ]: 50 : if (tracequery_obj !="" && file_exists(tracequery_obj))
[ + - ][ + + ]
[ + + ]
9857 : : {
9858 [ + - ]: 39 : copy_file(tracequery_obj, tracequery_path, s.verbose > 2);
9859 [ + - ]: 39 : modules.push_back (tracequery_path);
9860 : : }
9861 : : else
9862 : : // cache an empty file for failures
9863 [ + - ][ + - ]: 11 : copy_file("/dev/null", tracequery_path, s.verbose > 2);
[ + - ]
9864 [ + - ][ + - ]: 84 : }
[ + - ][ + + ]
[ + - ][ + + ]
9865 : : }
9866 : :
9867 : :
9868 : :
9869 : : bool
9870 : 592 : tracepoint_builder::init_dw(systemtap_session& s)
9871 : : {
9872 [ + + ]: 592 : if (dw != NULL)
9873 : 508 : return true;
9874 : :
9875 [ + - ]: 84 : vector<string> tracequery_modules;
9876 [ + - ]: 84 : vector<string> system_headers;
9877 : :
9878 : : glob_t trace_glob;
9879 : :
9880 : : // find kernel_source_tree
9881 [ + - ][ + - ]: 84 : if (s.kernel_source_tree == "")
9882 : : {
9883 : : unsigned found;
9884 [ + - ][ + - ]: 84 : DwflPtr dwfl_ptr = setup_dwfl_kernel ("kernel", &found, s);
[ + - ]
9885 : 84 : Dwfl *dwfl = dwfl_ptr.get()->dwfl;
9886 [ + - ]: 84 : if (found)
9887 : : {
9888 : 84 : Dwarf_Die *cudie = 0;
9889 : : Dwarf_Addr bias;
9890 [ + - ][ + - ]: 168 : while ((cudie = dwfl_nextcu (dwfl, cudie, &bias)) != NULL)
9891 : : {
9892 [ + - ]: 84 : assert_no_interrupts();
9893 : : Dwarf_Attribute attr;
9894 [ + - ][ + - ]: 84 : const char* name = dwarf_formstring (dwarf_attr (cudie, DW_AT_comp_dir, &attr));
9895 [ + - ]: 84 : if (name)
9896 : : {
9897 [ - + ]: 84 : if (s.verbose > 2)
9898 [ # # ][ # # ]: 0 : clog << _F("Located kernel source tree (DW_AT_comp_dir) at '%s'", name) << endl;
[ # # ][ # # ]
9899 : :
9900 [ + - ]: 84 : s.kernel_source_tree = name;
9901 : : break; // skip others; modern Kbuild uses same comp_dir for them all
9902 : : }
9903 : : }
9904 [ + - ]: 84 : }
9905 : : }
9906 : :
9907 : : // prefixes
9908 [ + - ]: 84 : vector<string> glob_prefixes;
9909 [ + - ]: 84 : glob_prefixes.push_back (s.kernel_build_tree);
9910 [ + - ][ + - ]: 84 : if (s.kernel_source_tree != "")
9911 [ + - ]: 84 : glob_prefixes.push_back (s.kernel_source_tree);
9912 : :
9913 : : // suffixes
9914 [ + - ]: 84 : vector<string> glob_suffixes;
9915 [ + - ][ + - ]: 84 : glob_suffixes.push_back("include/trace/events/*.h");
[ + - ]
9916 [ + - ][ + - ]: 84 : glob_suffixes.push_back("include/trace/*.h");
[ + - ]
9917 [ + - ][ + - ]: 84 : glob_suffixes.push_back("arch/x86/kvm/*trace.h");
[ + - ]
9918 [ + - ][ + - ]: 84 : glob_suffixes.push_back("fs/xfs/linux-*/xfs_tr*.h");
[ + - ]
9919 [ + - ][ + - ]: 84 : glob_suffixes.push_back("fs/xfs/xfs_trace*.h");
[ + - ]
9920 : :
9921 : : // compute cartesian product
9922 [ + - ]: 84 : vector<string> globs;
9923 [ + + ]: 252 : for (unsigned i=0; i<glob_prefixes.size(); i++)
9924 [ + + ]: 1008 : for (unsigned j=0; j<glob_suffixes.size(); j++)
9925 [ + - ][ + - ]: 840 : globs.push_back (glob_prefixes[i]+string("/")+glob_suffixes[j]);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
9926 : :
9927 [ + - ]: 84 : set<string> duped_headers;
9928 [ + + ]: 924 : for (unsigned z = 0; z < globs.size(); z++)
9929 : : {
9930 [ + - ]: 840 : string glob_str = globs[z];
9931 [ - + ]: 840 : if (s.verbose > 3)
9932 [ # # ][ # # ]: 0 : clog << _("Checking tracepoint glob ") << glob_str << endl;
[ # # ]
9933 : :
9934 [ + - ]: 840 : int r = glob(glob_str.c_str(), 0, NULL, &trace_glob);
9935 [ + - ][ - + ]: 840 : if (r == GLOB_NOSPACE || r == GLOB_ABORTED)
9936 [ # # ][ # # ]: 0 : throw runtime_error("Error globbing tracepoint");
9937 : :
9938 [ + + ]: 9072 : for (unsigned i = 0; i < trace_glob.gl_pathc; ++i)
9939 : : {
9940 [ + - ]: 8232 : string header(trace_glob.gl_pathv[i]);
9941 : :
9942 : : // filter out a few known "internal-only" headers
9943 [ + - ][ + + ]: 32088 : if (endswith(header, "/define_trace.h") ||
[ + + ][ + - ]
[ - + ][ + + ]
9944 [ + - ]: 8064 : endswith(header, "/ftrace.h") ||
9945 [ + - ]: 7896 : endswith(header, "/trace_events.h") ||
9946 [ + - ]: 7896 : endswith(header, "_event_types.h"))
9947 : 336 : continue;
9948 : :
9949 : : // skip identical headers from the build and source trees.
9950 [ + - ]: 7896 : size_t root_pos = header.rfind("include/");
9951 [ + + ][ + + ]: 23184 : if (root_pos != string::npos &&
[ + + ]
9952 [ + - ][ + - ]: 15288 : !duped_headers.insert(header.substr(root_pos + 8)).second)
[ + + ][ + + ]
[ + - ]
[ # # # # ]
9953 : 3696 : continue;
9954 : :
9955 [ + - ]: 4200 : system_headers.push_back(header);
9956 [ + - ][ + + ]: 8232 : }
9957 : 840 : globfree(&trace_glob);
9958 [ + - ]: 840 : }
9959 : :
9960 : : // Build tracequery modules
9961 [ + - ]: 84 : get_tracequery_modules(s, system_headers, tracequery_modules);
9962 : :
9963 : : // TODO: consider other sources of tracepoint headers too, like from
9964 : : // a command-line parameter or some environment or .systemtaprc
9965 : :
9966 [ + - ][ + - ]: 84 : dw = new dwflpp(s, tracequery_modules, true);
9967 [ + - ][ + - ]: 592 : return true;
[ + - ][ + - ]
[ + - ][ + - ]
9968 : : }
9969 : :
9970 : : void
9971 : 592 : tracepoint_builder::build(systemtap_session& s,
9972 : : probe *base, probe_point *location,
9973 : : literal_map_t const& parameters,
9974 : : vector<derived_probe*>& finished_results)
9975 : : {
9976 [ + - ][ + - ]: 592 : if (!init_dw(s))
9977 : 592 : return;
9978 : :
9979 [ + - ]: 592 : string tracepoint;
9980 [ + - ][ - + ]: 592 : assert(get_param (parameters, TOK_TRACE, tracepoint));
9981 : :
9982 [ + - ]: 592 : tracepoint_query q(*dw, tracepoint, base, location, finished_results);
9983 [ + - ][ + - ]: 592 : dw->iterate_over_modules(&query_module, &q);
[ + - ]
9984 : : }
9985 : :
9986 : :
9987 : : // ------------------------------------------------------------------------
9988 : : // Standard tapset registry.
9989 : : // ------------------------------------------------------------------------
9990 : :
9991 : : void
9992 : 1218 : register_standard_tapsets(systemtap_session & s)
9993 : : {
9994 : 1218 : register_tapset_been(s);
9995 : 1218 : register_tapset_itrace(s);
9996 : 1218 : register_tapset_mark(s);
9997 : 1218 : register_tapset_procfs(s);
9998 : 1218 : register_tapset_timers(s);
9999 : 1218 : register_tapset_netfilter(s);
10000 : 1218 : register_tapset_utrace(s);
10001 : :
10002 : : // dwarf-based kprobe/uprobe parts
10003 : 1218 : dwarf_derived_probe::register_patterns(s);
10004 : :
10005 : : // XXX: user-space starter set
10006 : : s.pattern_root->bind_num(TOK_PROCESS)
10007 : : ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
10008 : : ->bind_privilege(pr_all)
10009 : 1218 : ->bind(new uprobe_builder ());
10010 : : s.pattern_root->bind_num(TOK_PROCESS)
10011 : : ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN)
10012 : : ->bind_privilege(pr_all)
10013 : 1218 : ->bind(new uprobe_builder ());
10014 : :
10015 : : // kernel tracepoint probes
10016 : : s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_TRACE)
10017 : 1218 : ->bind(new tracepoint_builder());
10018 : :
10019 : : // Kprobe based probe
10020 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)
10021 : 1218 : ->bind(new kprobe_builder());
10022 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_CALL)
10023 : 1218 : ->bind(new kprobe_builder());
10024 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
10025 : 1218 : ->bind_str(TOK_FUNCTION)->bind(new kprobe_builder());
10026 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
10027 : 1218 : ->bind_str(TOK_FUNCTION)->bind(TOK_CALL)->bind(new kprobe_builder());
10028 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
10029 : 1218 : ->bind(new kprobe_builder());
10030 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
10031 : 1218 : ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder());
10032 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
10033 : 1218 : ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)->bind(new kprobe_builder());
10034 : : s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE)
10035 : : ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)
10036 : 1218 : ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder());
10037 : : s.pattern_root->bind(TOK_KPROBE)->bind_num(TOK_STATEMENT)
10038 : 1218 : ->bind(TOK_ABSOLUTE)->bind(new kprobe_builder());
10039 : :
10040 : : //Hwbkpt based probe
10041 : : // NB: we formerly registered the probe point types only if the kernel configuration
10042 : : // allowed it. However, we get better error messages if we allow probes to resolve.
10043 : : s.pattern_root->bind(TOK_KERNEL)->bind_num(TOK_HWBKPT)
10044 : 1218 : ->bind(TOK_HWBKPT_WRITE)->bind(new hwbkpt_builder());
10045 : : s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_HWBKPT)
10046 : 1218 : ->bind(TOK_HWBKPT_WRITE)->bind(new hwbkpt_builder());
10047 : : s.pattern_root->bind(TOK_KERNEL)->bind_num(TOK_HWBKPT)
10048 : 1218 : ->bind(TOK_HWBKPT_RW)->bind(new hwbkpt_builder());
10049 : : s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_HWBKPT)
10050 : 1218 : ->bind(TOK_HWBKPT_RW)->bind(new hwbkpt_builder());
10051 : : s.pattern_root->bind(TOK_KERNEL)->bind_num(TOK_HWBKPT)
10052 : 1218 : ->bind_num(TOK_LENGTH)->bind(TOK_HWBKPT_WRITE)->bind(new hwbkpt_builder());
10053 : : s.pattern_root->bind(TOK_KERNEL)->bind_num(TOK_HWBKPT)
10054 : 1218 : ->bind_num(TOK_LENGTH)->bind(TOK_HWBKPT_RW)->bind(new hwbkpt_builder());
10055 : : // length supported with address only, not symbol names
10056 : :
10057 : : //perf event based probe
10058 : 1218 : register_tapset_perf(s);
10059 : 1218 : }
10060 : :
10061 : :
10062 : : vector<derived_probe_group*>
10063 : 1932 : all_session_groups(systemtap_session& s)
10064 : : {
10065 : 1932 : vector<derived_probe_group*> g;
10066 : :
10067 : : #define DOONE(x) \
10068 : : if (s. x##_derived_probes) \
10069 : : g.push_back ((derived_probe_group*)(s. x##_derived_probes))
10070 : :
10071 : : // Note that order *is* important here. We want to make sure we
10072 : : // register (actually run) begin probes before any other probe type
10073 : : // is run. Similarly, when unregistering probes, we want to
10074 : : // unregister (actually run) end probes after every other probe type
10075 : : // has be unregistered. To do the latter,
10076 : : // c_unparser::emit_module_exit() will run this list backwards.
10077 [ + + ][ + - ]: 1932 : DOONE(be);
10078 [ + + ][ + - ]: 1932 : DOONE(dwarf);
10079 [ + + ][ + - ]: 1932 : DOONE(uprobe);
10080 [ + + ][ + - ]: 1932 : DOONE(timer);
10081 [ + + ][ + - ]: 1932 : DOONE(profile);
10082 [ - + ][ # # ]: 1932 : DOONE(mark);
10083 [ + + ][ + - ]: 1932 : DOONE(tracepoint);
10084 [ + + ][ + - ]: 1932 : DOONE(kprobe);
10085 [ + + ][ + - ]: 1932 : DOONE(hwbkpt);
10086 [ + + ][ + - ]: 1932 : DOONE(perf);
10087 [ + + ][ + - ]: 1932 : DOONE(hrtimer);
10088 [ + + ][ + - ]: 1932 : DOONE(procfs);
10089 [ + + ][ + - ]: 1932 : DOONE(netfilter);
10090 : :
10091 : : // Another "order is important" item. We want to make sure we
10092 : : // "register" the dummy task_finder probe group after all probe
10093 : : // groups that use the task_finder.
10094 [ + + ][ + - ]: 1932 : DOONE(utrace);
10095 [ - + ][ # # ]: 1932 : DOONE(itrace);
10096 [ - + ][ # # ]: 1932 : DOONE(dynprobe);
10097 [ + + ][ + - ]: 1932 : DOONE(task_finder);
10098 : : #undef DOONE
10099 : 1932 : return g;
10100 [ + - ][ + - ]: 7242 : }
10101 : :
10102 : : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
|