]> sourceware.org Git - systemtap.git/blob - dwflpp.h
Add more syntax for shared library probing.
[systemtap.git] / dwflpp.h
1 // C++ interface to dwfl
2 // Copyright (C) 2005-2010 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 #ifndef DWFLPP_H
12 #define DWFLPP_H
13
14 #include "config.h"
15 #include "dwarf_wrappers.h"
16 #include "elaborate.h"
17 #include "session.h"
18 #include "unordered.h"
19 #include "setupdwfl.h"
20
21 #include <cstring>
22 #include <iostream>
23 #include <map>
24 #include <set>
25 #include <string>
26 #include <vector>
27
28 extern "C" {
29 #include <elfutils/libdwfl.h>
30 #include <regex.h>
31 }
32
33 #if !_ELFUTILS_PREREQ(0,142)
34 // Always use newer name, old name is deprecated in 0.142.
35 #define elf_getshdrstrndx elf_getshstrndx
36 #endif
37
38
39 struct func_info;
40 struct inline_instance_info;
41 struct symbol_table;
42 struct base_query;
43 struct dwarf_query;
44
45 enum line_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD };
46 enum info_status { info_unknown, info_present, info_absent };
47
48 // module -> cu die[]
49 typedef unordered_map<Dwarf*, std::vector<Dwarf_Die>*> module_cu_cache_t;
50
51 // typename -> die
52 typedef unordered_map<std::string, Dwarf_Die> cu_type_cache_t;
53
54 // cu die -> (typename -> die)
55 typedef unordered_map<void*, cu_type_cache_t*> mod_cu_type_cache_t;
56
57 // function -> die
58 typedef unordered_multimap<std::string, Dwarf_Die> cu_function_cache_t;
59 typedef std::pair<cu_function_cache_t::iterator,
60 cu_function_cache_t::iterator>
61 cu_function_cache_range_t;
62
63 // cu die -> (function -> die)
64 typedef unordered_map<void*, cu_function_cache_t*> mod_cu_function_cache_t;
65
66 // module -> (function -> die)
67 typedef unordered_map<Dwarf*, cu_function_cache_t*> mod_function_cache_t;
68
69 // inline function die -> instance die[]
70 typedef unordered_map<void*, std::vector<Dwarf_Die>*> cu_inl_function_cache_t;
71
72 // die -> parent die
73 typedef unordered_map<void*, Dwarf_Die> cu_die_parent_cache_t;
74
75 // cu die -> (die -> parent die)
76 typedef unordered_map<void*, cu_die_parent_cache_t*> mod_cu_die_parent_cache_t;
77
78 typedef std::vector<func_info> func_info_map_t;
79 typedef std::vector<inline_instance_info> inline_instance_map_t;
80
81
82 /* XXX FIXME functions that dwflpp needs from tapsets.cxx */
83 func_info_map_t *get_filtered_functions(dwarf_query *q);
84 inline_instance_map_t *get_filtered_inlines(dwarf_query *q);
85
86
87 struct
88 module_info
89 {
90 Dwfl_Module* mod;
91 const char* name;
92 std::string elf_path;
93 Dwarf_Addr addr;
94 Dwarf_Addr bias;
95 symbol_table *sym_table;
96 info_status dwarf_status; // module has dwarf info?
97 info_status symtab_status; // symbol table cached?
98
99 void get_symtab(dwarf_query *q);
100 void update_symtab(cu_function_cache_t *funcs);
101
102 module_info(const char *name) :
103 mod(NULL),
104 name(name),
105 addr(0),
106 bias(0),
107 sym_table(NULL),
108 dwarf_status(info_unknown),
109 symtab_status(info_unknown)
110 {}
111
112 ~module_info();
113 };
114
115
116 struct
117 module_cache
118 {
119 std::map<std::string, module_info*> cache;
120 bool paths_collected;
121 bool dwarf_collected;
122
123 module_cache() : paths_collected(false), dwarf_collected(false) {}
124 ~module_cache();
125 };
126
127
128 struct func_info
129 {
130 func_info()
131 : decl_file(NULL), decl_line(-1), addr(0), prologue_end(0), weak(false), descriptor(false)
132 {
133 std::memset(&die, 0, sizeof(die));
134 }
135 std::string name;
136 char const * decl_file;
137 int decl_line;
138 Dwarf_Die die;
139 Dwarf_Addr addr;
140 Dwarf_Addr entrypc;
141 Dwarf_Addr prologue_end;
142 bool weak, descriptor;
143 };
144
145
146 struct inline_instance_info
147 {
148 inline_instance_info()
149 : decl_file(NULL), decl_line(-1)
150 {
151 std::memset(&die, 0, sizeof(die));
152 }
153 bool operator<(const inline_instance_info& other) const;
154 std::string name;
155 char const * decl_file;
156 int decl_line;
157 Dwarf_Addr entrypc;
158 Dwarf_Die die;
159 };
160
161
162 struct dwflpp
163 {
164 systemtap_session & sess;
165
166 // These are "current" values we focus on.
167 Dwfl_Module * module;
168 Dwarf_Addr module_bias;
169 module_info * mod_info;
170
171 // These describe the current module's PC address range
172 Dwarf_Addr module_start;
173 Dwarf_Addr module_end;
174
175 Dwarf_Die * cu;
176
177 std::string module_name;
178 std::string function_name;
179
180 dwflpp(systemtap_session & session, const std::string& user_module, bool kernel_p);
181 dwflpp(systemtap_session & session, const std::vector<std::string>& user_modules, bool kernel_p);
182 ~dwflpp();
183
184 void get_module_dwarf(bool required = false, bool report = true);
185
186 void focus_on_module(Dwfl_Module * m, module_info * mi);
187 void focus_on_cu(Dwarf_Die * c);
188 void focus_on_function(Dwarf_Die * f);
189
190 std::string cu_name(void);
191
192 Dwarf_Die *query_cu_containing_address(Dwarf_Addr a);
193
194 bool module_name_matches(const std::string& pattern);
195 static bool name_has_wildcard(const std::string& pattern);
196 bool module_name_final_match(const std::string& pattern);
197
198 bool function_name_matches_pattern(const std::string& name, const std::string& pattern);
199 bool function_name_matches(const std::string& pattern);
200 bool function_scope_matches(const std::vector<std::string>& scopes);
201
202 void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
203 const char *, Dwarf_Addr,
204 void *),
205 base_query *data);
206
207 void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
208 void * data);
209
210 bool func_is_inline();
211
212 void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
213 void * data);
214
215 std::vector<Dwarf_Die> getscopes_die(Dwarf_Die* die);
216 std::vector<Dwarf_Die> getscopes(Dwarf_Die* die);
217 std::vector<Dwarf_Die> getscopes(Dwarf_Addr pc);
218
219 Dwarf_Die *declaration_resolve(Dwarf_Die *type);
220 Dwarf_Die *declaration_resolve(const std::string& name);
221 Dwarf_Die *declaration_resolve_other_cus(const std::string& name);
222
223 int iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q),
224 base_query * q, const std::string& function);
225
226 int iterate_single_function (int (* callback)(Dwarf_Die * func, base_query * q),
227 base_query * q, const std::string& function);
228
229 void iterate_over_srcfile_lines (char const * srcfile,
230 int lines[2],
231 bool need_single_match,
232 enum line_t line_type,
233 void (* callback) (const dwarf_line_t& line,
234 void * arg),
235 const std::string& func_pattern,
236 void *data);
237
238 void iterate_over_labels (Dwarf_Die *begin_die,
239 const std::string& sym,
240 const std::string& function,
241 dwarf_query *q,
242 void (* callback)(const std::string &,
243 const char *,
244 const char *,
245 int,
246 Dwarf_Die *,
247 Dwarf_Addr,
248 dwarf_query *));
249
250 int iterate_over_notes (void *object,
251 void (*callback)(void *object, int type,
252 const char *data, size_t len));
253
254 void iterate_over_libraries (void (*callback)(void *object,
255 int type, const char *data), base_query *data);
256
257
258 GElf_Shdr * get_section(std::string section_name, GElf_Shdr *shdr_mem,
259 Elf **elf_ret=NULL);
260
261 void collect_srcfiles_matching (std::string const & pattern,
262 std::set<std::string> & filtered_srcfiles);
263
264 void resolve_prologue_endings (func_info_map_t & funcs);
265
266 bool function_entrypc (Dwarf_Addr * addr);
267 bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr);
268
269 void function_die (Dwarf_Die *d);
270 void function_file (char const ** c);
271 void function_line (int *linep);
272
273 bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc);
274 bool inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
275 Dwarf_Die& result);
276
277 std::string literal_stmt_for_local (std::vector<Dwarf_Die>& scopes,
278 Dwarf_Addr pc,
279 std::string const & local,
280 const target_symbol *e,
281 bool lvalue,
282 exp_type & ty);
283 Dwarf_Die* type_die_for_local (std::vector<Dwarf_Die>& scopes,
284 Dwarf_Addr pc,
285 std::string const & local,
286 const target_symbol *e,
287 Dwarf_Die *die_mem);
288
289 std::string literal_stmt_for_return (Dwarf_Die *scope_die,
290 Dwarf_Addr pc,
291 const target_symbol *e,
292 bool lvalue,
293 exp_type & ty);
294 Dwarf_Die* type_die_for_return (Dwarf_Die *scope_die,
295 Dwarf_Addr pc,
296 const target_symbol *e,
297 Dwarf_Die *die_mem);
298
299 std::string literal_stmt_for_pointer (Dwarf_Die *type_die,
300 const target_symbol *e,
301 bool lvalue,
302 exp_type & ty);
303 Dwarf_Die* type_die_for_pointer (Dwarf_Die *type_die,
304 const target_symbol *e,
305 Dwarf_Die *die_mem);
306
307 bool blacklisted_p(const std::string& funcname,
308 const std::string& filename,
309 int line,
310 const std::string& module,
311 Dwarf_Addr addr,
312 bool has_return);
313
314 Dwarf_Addr relocate_address(Dwarf_Addr addr, std::string& reloc_section);
315
316 void resolve_unqualified_inner_typedie (Dwarf_Die *typedie,
317 Dwarf_Die *innerdie,
318 const target_symbol *e);
319
320
321 private:
322 DwflPtr dwfl_ptr;
323
324 // These are "current" values we focus on.
325 Dwarf * module_dwarf;
326 Dwarf_Die * function;
327
328 void setup_kernel(const std::string& module_name, bool debuginfo_needed = true);
329 void setup_kernel(const std::vector<std::string>& modules, bool debuginfo_needed = true);
330 void setup_user(const std::vector<std::string>& modules, bool debuginfo_needed = true);
331
332 module_cu_cache_t module_cu_cache;
333 mod_cu_function_cache_t cu_function_cache;
334 mod_function_cache_t mod_function_cache;
335
336 std::set<void*> cu_inl_function_cache_done; // CUs that are already cached
337 cu_inl_function_cache_t cu_inl_function_cache;
338 void cache_inline_instances (Dwarf_Die* die);
339
340 mod_cu_die_parent_cache_t cu_die_parent_cache;
341 void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die);
342 cu_die_parent_cache_t *get_die_parents();
343
344 Dwarf_Die* get_parent_scope(Dwarf_Die* die);
345
346 /* The global alias cache is used to resolve any DIE found in a
347 * module that is stubbed out with DW_AT_declaration with a defining
348 * DIE found in a different module. The current assumption is that
349 * this only applies to structures and unions, which have a global
350 * namespace (it deliberately only traverses program scope), so this
351 * cache is indexed by name. If other declaration lookups were
352 * added to it, it would have to be indexed by name and tag
353 */
354 mod_cu_type_cache_t global_alias_cache;
355 static int global_alias_caching_callback(Dwarf_Die *die, void *arg);
356 static int global_alias_caching_callback_cus(Dwarf_Die *die, void *arg);
357 static int iterate_over_globals (Dwarf_Die *,
358 int (* callback)(Dwarf_Die *, void *),
359 void * data);
360
361 static int mod_function_caching_callback (Dwarf_Die* func, void *arg);
362 static int cu_function_caching_callback (Dwarf_Die* func, void *arg);
363
364 bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
365
366 static void loc2c_error (void *, const char *fmt, ...);
367
368 // This function generates code used for addressing computations of
369 // target variables.
370 void emit_address (struct obstack *pool, Dwarf_Addr address);
371 static void loc2c_emit_address (void *arg, struct obstack *pool,
372 Dwarf_Addr address);
373
374 void print_locals(std::vector<Dwarf_Die>& scopes, std::ostream &o);
375 void print_members(Dwarf_Die *vardie, std::ostream &o);
376
377 Dwarf_Attribute *find_variable_and_frame_base (std::vector<Dwarf_Die>& scopes,
378 Dwarf_Addr pc,
379 std::string const & local,
380 const target_symbol *e,
381 Dwarf_Die *vardie,
382 Dwarf_Attribute *fb_attr_mem);
383
384 struct location *translate_location(struct obstack *pool,
385 Dwarf_Attribute *attr,
386 Dwarf_Die *die,
387 Dwarf_Addr pc,
388 Dwarf_Attribute *fb_attr,
389 struct location **tail,
390 const target_symbol *e);
391
392 bool find_struct_member(const target_symbol::component& c,
393 Dwarf_Die *parentdie,
394 Dwarf_Die *memberdie,
395 std::vector<Dwarf_Die>& dies,
396 std::vector<Dwarf_Attribute>& locs);
397
398 void translate_components(struct obstack *pool,
399 struct location **tail,
400 Dwarf_Addr pc,
401 const target_symbol *e,
402 Dwarf_Die *vardie,
403 Dwarf_Die *typedie,
404 unsigned first=0);
405
406 void translate_final_fetch_or_store (struct obstack *pool,
407 struct location **tail,
408 Dwarf_Addr module_bias,
409 Dwarf_Die *vardie,
410 Dwarf_Die *typedie,
411 bool lvalue,
412 const target_symbol *e,
413 std::string &,
414 std::string &,
415 exp_type & ty);
416
417 std::string express_as_string (std::string prelude,
418 std::string postlude,
419 struct location *head);
420
421 regex_t blacklist_func; // function/statement probes
422 regex_t blacklist_func_ret; // only for .return probes
423 regex_t blacklist_file; // file name
424 regex_t blacklist_section; // init/exit sections
425 bool blacklist_enabled;
426 void build_blacklist();
427 std::string get_blacklist_section(Dwarf_Addr addr);
428
429 // Returns the call frame address operations for the given program counter.
430 Dwarf_Op *get_cfa_ops (Dwarf_Addr pc);
431
432 Dwarf_Addr vardie_from_symtable(Dwarf_Die *vardie, Dwarf_Addr *addr);
433 };
434
435 #endif // DWFLPP_H
436
437 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.055568 seconds and 6 git commands to generate.