1 // C++ interface to dwfl
2 // Copyright (C) 2005-2010 Red Hat Inc.
3 // Copyright (C) 2005-2007 Intel Corporation.
4 // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
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
15 #include "dwarf_wrappers.h"
16 #include "elaborate.h"
18 #include "unordered.h"
19 #include "setupdwfl.h"
29 #include <elfutils/libdwfl.h>
33 #if !_ELFUTILS_PREREQ(0,142)
34 // Always use newer name, old name is deprecated in 0.142.
35 #define elf_getshdrstrndx elf_getshstrndx
40 struct inline_instance_info
;
45 enum line_t
{ ABSOLUTE
, RELATIVE
, RANGE
, WILDCARD
};
46 enum info_status
{ info_unknown
, info_present
, info_absent
};
49 typedef unordered_map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
52 typedef unordered_map
<std::string
, Dwarf_Die
> cu_type_cache_t
;
54 // cu die -> (typename -> die)
55 typedef unordered_map
<void*, cu_type_cache_t
*> mod_cu_type_cache_t
;
58 typedef unordered_multimap
<std::string
, Dwarf_Die
> cu_function_cache_t
;
59 typedef std::pair
<cu_function_cache_t::iterator
,
60 cu_function_cache_t::iterator
>
61 cu_function_cache_range_t
;
63 // cu die -> (function -> die)
64 typedef unordered_map
<void*, cu_function_cache_t
*> mod_cu_function_cache_t
;
66 // module -> (function -> die)
67 typedef unordered_map
<Dwarf
*, cu_function_cache_t
*> mod_function_cache_t
;
69 // inline function die -> instance die[]
70 typedef unordered_map
<void*, std::vector
<Dwarf_Die
>*> cu_inl_function_cache_t
;
73 typedef unordered_map
<void*, Dwarf_Die
> cu_die_parent_cache_t
;
75 // cu die -> (die -> parent die)
76 typedef unordered_map
<void*, cu_die_parent_cache_t
*> mod_cu_die_parent_cache_t
;
78 typedef std::vector
<func_info
> func_info_map_t
;
79 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
82 /* XXX FIXME functions that dwflpp needs from tapsets.cxx */
83 func_info_map_t
*get_filtered_functions(dwarf_query
*q
);
84 inline_instance_map_t
*get_filtered_inlines(dwarf_query
*q
);
95 symbol_table
*sym_table
;
96 info_status dwarf_status
; // module has dwarf info?
97 info_status symtab_status
; // symbol table cached?
99 void get_symtab(dwarf_query
*q
);
100 void update_symtab(cu_function_cache_t
*funcs
);
102 module_info(const char *name
) :
108 dwarf_status(info_unknown
),
109 symtab_status(info_unknown
)
119 std::map
<std::string
, module_info
*> cache
;
120 bool paths_collected
;
121 bool dwarf_collected
;
123 module_cache() : paths_collected(false), dwarf_collected(false) {}
131 : decl_file(NULL
), decl_line(-1), addr(0), prologue_end(0), weak(false), descriptor(false)
133 std::memset(&die
, 0, sizeof(die
));
136 char const * decl_file
;
141 Dwarf_Addr prologue_end
;
142 bool weak
, descriptor
;
146 struct inline_instance_info
148 inline_instance_info()
149 : decl_file(NULL
), decl_line(-1)
151 std::memset(&die
, 0, sizeof(die
));
153 bool operator<(const inline_instance_info
& other
) const;
155 char const * decl_file
;
164 systemtap_session
& sess
;
166 // These are "current" values we focus on.
167 Dwfl_Module
* module
;
168 Dwarf_Addr module_bias
;
169 module_info
* mod_info
;
171 // These describe the current module's PC address range
172 Dwarf_Addr module_start
;
173 Dwarf_Addr module_end
;
177 std::string module_name
;
178 std::string function_name
;
180 dwflpp(systemtap_session
& session
, const std::string
& user_module
, bool kernel_p
);
181 dwflpp(systemtap_session
& session
, const std::vector
<std::string
>& user_modules
, bool kernel_p
);
184 void get_module_dwarf(bool required
= false, bool report
= true);
186 void focus_on_module(Dwfl_Module
* m
, module_info
* mi
);
187 void focus_on_cu(Dwarf_Die
* c
);
188 void focus_on_function(Dwarf_Die
* f
);
190 std::string
cu_name(void);
192 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
194 bool module_name_matches(const std::string
& pattern
);
195 static bool name_has_wildcard(const std::string
& pattern
);
196 bool module_name_final_match(const std::string
& pattern
);
198 bool function_name_matches_pattern(const std::string
& name
, const std::string
& pattern
);
199 bool function_name_matches(const std::string
& pattern
);
200 bool function_scope_matches(const std::vector
<std::string
>& scopes
);
202 void iterate_over_modules(int (* callback
)(Dwfl_Module
*, void **,
203 const char *, Dwarf_Addr
,
207 void iterate_over_cus (int (*callback
)(Dwarf_Die
* die
, void * arg
),
210 bool func_is_inline();
212 void iterate_over_inline_instances (int (* callback
)(Dwarf_Die
* die
, void * arg
),
215 std::vector
<Dwarf_Die
> getscopes_die(Dwarf_Die
* die
);
216 std::vector
<Dwarf_Die
> getscopes(Dwarf_Die
* die
);
217 std::vector
<Dwarf_Die
> getscopes(Dwarf_Addr pc
);
219 Dwarf_Die
*declaration_resolve(Dwarf_Die
*type
);
220 Dwarf_Die
*declaration_resolve(const std::string
& name
);
221 Dwarf_Die
*declaration_resolve_other_cus(const std::string
& name
);
223 int iterate_over_functions (int (* callback
)(Dwarf_Die
* func
, base_query
* q
),
224 base_query
* q
, const std::string
& function
);
226 int iterate_single_function (int (* callback
)(Dwarf_Die
* func
, base_query
* q
),
227 base_query
* q
, const std::string
& function
);
229 void iterate_over_srcfile_lines (char const * srcfile
,
231 bool need_single_match
,
232 enum line_t line_type
,
233 void (* callback
) (const dwarf_line_t
& line
,
235 const std::string
& func_pattern
,
238 void iterate_over_labels (Dwarf_Die
*begin_die
,
239 const std::string
& sym
,
240 const std::string
& function
,
242 void (* callback
)(const std::string
&,
250 int iterate_over_notes (void *object
,
251 void (*callback
)(void *object
, int type
,
252 const char *data
, size_t len
));
254 void iterate_over_libraries (void (*callback
)(void *object
,
255 int type
, const char *data
), base_query
*data
);
258 GElf_Shdr
* get_section(std::string section_name
, GElf_Shdr
*shdr_mem
,
261 void collect_srcfiles_matching (std::string
const & pattern
,
262 std::set
<std::string
> & filtered_srcfiles
);
264 void resolve_prologue_endings (func_info_map_t
& funcs
);
266 bool function_entrypc (Dwarf_Addr
* addr
);
267 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
);
269 void function_die (Dwarf_Die
*d
);
270 void function_file (char const ** c
);
271 void function_line (int *linep
);
273 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
274 bool inner_die_containing_pc(Dwarf_Die
& scope
, Dwarf_Addr addr
,
277 std::string
literal_stmt_for_local (std::vector
<Dwarf_Die
>& scopes
,
279 std::string
const & local
,
280 const target_symbol
*e
,
283 Dwarf_Die
* type_die_for_local (std::vector
<Dwarf_Die
>& scopes
,
285 std::string
const & local
,
286 const target_symbol
*e
,
289 std::string
literal_stmt_for_return (Dwarf_Die
*scope_die
,
291 const target_symbol
*e
,
294 Dwarf_Die
* type_die_for_return (Dwarf_Die
*scope_die
,
296 const target_symbol
*e
,
299 std::string
literal_stmt_for_pointer (Dwarf_Die
*type_die
,
300 const target_symbol
*e
,
303 Dwarf_Die
* type_die_for_pointer (Dwarf_Die
*type_die
,
304 const target_symbol
*e
,
307 bool blacklisted_p(const std::string
& funcname
,
308 const std::string
& filename
,
310 const std::string
& module
,
314 Dwarf_Addr
relocate_address(Dwarf_Addr addr
, std::string
& reloc_section
);
316 void resolve_unqualified_inner_typedie (Dwarf_Die
*typedie
,
318 const target_symbol
*e
);
324 // These are "current" values we focus on.
325 Dwarf
* module_dwarf
;
326 Dwarf_Die
* function
;
328 void setup_kernel(const std::string
& module_name
, bool debuginfo_needed
= true);
329 void setup_kernel(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
330 void setup_user(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
332 module_cu_cache_t module_cu_cache
;
333 mod_cu_function_cache_t cu_function_cache
;
334 mod_function_cache_t mod_function_cache
;
336 std::set
<void*> cu_inl_function_cache_done
; // CUs that are already cached
337 cu_inl_function_cache_t cu_inl_function_cache
;
338 void cache_inline_instances (Dwarf_Die
* die
);
340 mod_cu_die_parent_cache_t cu_die_parent_cache
;
341 void cache_die_parents(cu_die_parent_cache_t
* parents
, Dwarf_Die
* die
);
342 cu_die_parent_cache_t
*get_die_parents();
344 Dwarf_Die
* get_parent_scope(Dwarf_Die
* die
);
346 /* The global alias cache is used to resolve any DIE found in a
347 * module that is stubbed out with DW_AT_declaration with a defining
348 * DIE found in a different module. The current assumption is that
349 * this only applies to structures and unions, which have a global
350 * namespace (it deliberately only traverses program scope), so this
351 * cache is indexed by name. If other declaration lookups were
352 * added to it, it would have to be indexed by name and tag
354 mod_cu_type_cache_t global_alias_cache
;
355 static int global_alias_caching_callback(Dwarf_Die
*die
, void *arg
);
356 static int global_alias_caching_callback_cus(Dwarf_Die
*die
, void *arg
);
357 static int iterate_over_globals (Dwarf_Die
*,
358 int (* callback
)(Dwarf_Die
*, void *),
361 static int mod_function_caching_callback (Dwarf_Die
* func
, void *arg
);
362 static int cu_function_caching_callback (Dwarf_Die
* func
, void *arg
);
364 bool has_single_line_record (dwarf_query
* q
, char const * srcfile
, int lineno
);
366 static void loc2c_error (void *, const char *fmt
, ...);
368 // This function generates code used for addressing computations of
370 void emit_address (struct obstack
*pool
, Dwarf_Addr address
);
371 static void loc2c_emit_address (void *arg
, struct obstack
*pool
,
374 void print_locals(std::vector
<Dwarf_Die
>& scopes
, std::ostream
&o
);
375 void print_members(Dwarf_Die
*vardie
, std::ostream
&o
);
377 Dwarf_Attribute
*find_variable_and_frame_base (std::vector
<Dwarf_Die
>& scopes
,
379 std::string
const & local
,
380 const target_symbol
*e
,
382 Dwarf_Attribute
*fb_attr_mem
);
384 struct location
*translate_location(struct obstack
*pool
,
385 Dwarf_Attribute
*attr
,
388 Dwarf_Attribute
*fb_attr
,
389 struct location
**tail
,
390 const target_symbol
*e
);
392 bool find_struct_member(const target_symbol::component
& c
,
393 Dwarf_Die
*parentdie
,
394 Dwarf_Die
*memberdie
,
395 std::vector
<Dwarf_Die
>& dies
,
396 std::vector
<Dwarf_Attribute
>& locs
);
398 void translate_components(struct obstack
*pool
,
399 struct location
**tail
,
401 const target_symbol
*e
,
406 void translate_final_fetch_or_store (struct obstack
*pool
,
407 struct location
**tail
,
408 Dwarf_Addr module_bias
,
412 const target_symbol
*e
,
417 std::string
express_as_string (std::string prelude
,
418 std::string postlude
,
419 struct location
*head
);
421 regex_t blacklist_func
; // function/statement probes
422 regex_t blacklist_func_ret
; // only for .return probes
423 regex_t blacklist_file
; // file name
424 regex_t blacklist_section
; // init/exit sections
425 bool blacklist_enabled
;
426 void build_blacklist();
427 std::string
get_blacklist_section(Dwarf_Addr addr
);
429 // Returns the call frame address operations for the given program counter.
430 Dwarf_Op
*get_cfa_ops (Dwarf_Addr pc
);
432 Dwarf_Addr
vardie_from_symtable(Dwarf_Die
*vardie
, Dwarf_Addr
*addr
);
437 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */