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