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