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