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