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