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
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"
28 #include <elfutils/libdwfl.h>
32 #if !_ELFUTILS_PREREQ(0,142)
33 // Always use newer name, old name is deprecated in 0.142.
34 #define elf_getshdrstrndx elf_getshstrndx
39 struct inline_instance_info
;
44 enum line_t
{ ABSOLUTE
, RELATIVE
, RANGE
, WILDCARD
};
45 enum info_status
{ info_unknown
, info_present
, info_absent
};
48 typedef unordered_map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
51 typedef unordered_map
<std::string
, Dwarf_Die
> cu_type_cache_t
;
53 // cu die -> (typename -> die)
54 typedef unordered_map
<void*, cu_type_cache_t
*> mod_cu_type_cache_t
;
57 typedef unordered_multimap
<std::string
, Dwarf_Die
> cu_function_cache_t
;
58 typedef std::pair
<cu_function_cache_t::iterator
,
59 cu_function_cache_t::iterator
>
60 cu_function_cache_range_t
;
62 // cu die -> (function -> die)
63 typedef unordered_map
<void*, cu_function_cache_t
*> mod_cu_function_cache_t
;
65 // inline function die -> instance die[]
66 typedef unordered_map
<void*, std::vector
<Dwarf_Die
>*> cu_inl_function_cache_t
;
69 typedef unordered_map
<void*, Dwarf_Die
> cu_die_parent_cache_t
;
71 // cu die -> (die -> parent die)
72 typedef unordered_map
<void*, cu_die_parent_cache_t
*> mod_cu_die_parent_cache_t
;
74 typedef std::vector
<func_info
> func_info_map_t
;
75 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
78 /* XXX FIXME functions that dwflpp needs from tapsets.cxx */
79 func_info_map_t
*get_filtered_functions(dwarf_query
*q
);
80 inline_instance_map_t
*get_filtered_inlines(dwarf_query
*q
);
91 symbol_table
*sym_table
;
92 info_status dwarf_status
; // module has dwarf info?
93 info_status symtab_status
; // symbol table cached?
95 void get_symtab(dwarf_query
*q
);
96 void update_symtab(cu_function_cache_t
*funcs
);
98 module_info(const char *name
) :
104 dwarf_status(info_unknown
),
105 symtab_status(info_unknown
)
115 std::map
<std::string
, module_info
*> cache
;
116 bool paths_collected
;
117 bool dwarf_collected
;
119 module_cache() : paths_collected(false), dwarf_collected(false) {}
126 : decl_file(NULL
), decl_line(-1), addr(0), prologue_end(0), weak(false)
128 std::memset(&die
, 0, sizeof(die
));
131 char const * decl_file
;
136 Dwarf_Addr prologue_end
;
141 struct inline_instance_info
143 inline_instance_info()
144 : decl_file(NULL
), decl_line(-1)
146 std::memset(&die
, 0, sizeof(die
));
148 bool operator<(const inline_instance_info
& other
) const;
150 char const * decl_file
;
159 systemtap_session
& sess
;
161 // These are "current" values we focus on.
162 Dwfl_Module
* module
;
163 Dwarf_Addr module_bias
;
164 module_info
* mod_info
;
166 // These describe the current module's PC address range
167 Dwarf_Addr module_start
;
168 Dwarf_Addr module_end
;
172 std::string module_name
;
173 std::string function_name
;
175 dwflpp(systemtap_session
& session
, const std::string
& user_module
, bool kernel_p
);
176 dwflpp(systemtap_session
& session
, const std::vector
<std::string
>& user_modules
);
179 void get_module_dwarf(bool required
= false, bool report
= true);
181 void focus_on_module(Dwfl_Module
* m
, module_info
* mi
);
182 void focus_on_cu(Dwarf_Die
* c
);
183 void focus_on_function(Dwarf_Die
* f
);
185 std::string
cu_name(void);
187 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
189 bool module_name_matches(const std::string
& pattern
);
190 static bool name_has_wildcard(const std::string
& pattern
);
191 bool module_name_final_match(const std::string
& pattern
);
193 bool function_name_matches_pattern(const std::string
& name
, const std::string
& pattern
);
194 bool function_name_matches(const std::string
& pattern
);
195 bool function_scope_matches(const std::vector
<std::string
> scopes
);
197 void iterate_over_modules(int (* callback
)(Dwfl_Module
*, void **,
198 const char *, Dwarf_Addr
,
202 void iterate_over_cus (int (*callback
)(Dwarf_Die
* die
, void * arg
),
205 bool func_is_inline();
207 void iterate_over_inline_instances (int (* callback
)(Dwarf_Die
* die
, void * arg
),
210 std::vector
<Dwarf_Die
> getscopes_die(Dwarf_Die
* die
);
211 std::vector
<Dwarf_Die
> getscopes(Dwarf_Die
* die
);
212 std::vector
<Dwarf_Die
> getscopes(Dwarf_Addr pc
);
214 Dwarf_Die
*declaration_resolve(const char *name
);
216 mod_cu_function_cache_t cu_function_cache
;
218 int iterate_over_functions (int (* callback
)(Dwarf_Die
* func
, base_query
* q
),
219 base_query
* q
, const std::string
& function
,
220 bool has_statement_num
=false);
222 void iterate_over_srcfile_lines (char const * srcfile
,
224 bool need_single_match
,
225 enum line_t line_type
,
226 void (* callback
) (const dwarf_line_t
& line
,
228 const std::string
& func_pattern
,
231 void iterate_over_labels (Dwarf_Die
*begin_die
,
232 const std::string
& sym
,
233 const std::string
& function
,
235 void (* callback
)(const std::string
&,
243 void collect_srcfiles_matching (std::string
const & pattern
,
244 std::set
<std::string
> & filtered_srcfiles
);
246 void resolve_prologue_endings (func_info_map_t
& funcs
);
248 bool function_entrypc (Dwarf_Addr
* addr
);
249 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
);
251 void function_die (Dwarf_Die
*d
);
252 void function_file (char const ** c
);
253 void function_line (int *linep
);
255 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
257 std::string
literal_stmt_for_local (std::vector
<Dwarf_Die
>& scopes
,
259 std::string
const & local
,
260 const target_symbol
*e
,
265 std::string
literal_stmt_for_return (Dwarf_Die
*scope_die
,
267 const target_symbol
*e
,
271 std::string
literal_stmt_for_pointer (Dwarf_Die
*type_die
,
272 const target_symbol
*e
,
276 bool blacklisted_p(const std::string
& funcname
,
277 const std::string
& filename
,
279 const std::string
& module
,
283 Dwarf_Addr
relocate_address(Dwarf_Addr addr
, std::string
& reloc_section
);
285 Dwarf_Addr
literal_addr_to_sym_addr(Dwarf_Addr lit_addr
);
291 // These are "current" values we focus on.
292 Dwarf
* module_dwarf
;
293 Dwarf_Die
* function
;
295 void setup_kernel(const std::string
& module_name
, bool debuginfo_needed
= true);
296 void setup_user(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
298 module_cu_cache_t module_cu_cache
;
300 std::set
<void*> cu_inl_function_cache_done
; // CUs that are already cached
301 cu_inl_function_cache_t cu_inl_function_cache
;
302 void cache_inline_instances (Dwarf_Die
* die
);
304 mod_cu_die_parent_cache_t cu_die_parent_cache
;
305 void cache_die_parents(cu_die_parent_cache_t
* parents
, Dwarf_Die
* die
);
306 cu_die_parent_cache_t
*get_die_parents();
308 Dwarf_Die
* get_parent_scope(Dwarf_Die
* die
);
310 /* The global alias cache is used to resolve any DIE found in a
311 * module that is stubbed out with DW_AT_declaration with a defining
312 * DIE found in a different module. The current assumption is that
313 * this only applies to structures and unions, which have a global
314 * namespace (it deliberately only traverses program scope), so this
315 * cache is indexed by name. If other declaration lookups were
316 * added to it, it would have to be indexed by name and tag
318 mod_cu_type_cache_t global_alias_cache
;
319 static int global_alias_caching_callback(Dwarf_Die
*die
, void *arg
);
320 int iterate_over_globals (int (* callback
)(Dwarf_Die
*, void *),
323 static int cu_function_caching_callback (Dwarf_Die
* func
, void *arg
);
325 bool has_single_line_record (dwarf_query
* q
, char const * srcfile
, int lineno
);
327 static void loc2c_error (void *, const char *fmt
, ...);
329 // This function generates code used for addressing computations of
331 void emit_address (struct obstack
*pool
, Dwarf_Addr address
);
332 static void loc2c_emit_address (void *arg
, struct obstack
*pool
,
335 void print_locals(std::vector
<Dwarf_Die
>& scopes
, std::ostream
&o
);
336 void print_members(Dwarf_Die
*vardie
, std::ostream
&o
);
338 Dwarf_Attribute
*find_variable_and_frame_base (std::vector
<Dwarf_Die
>& scopes
,
340 std::string
const & local
,
341 const target_symbol
*e
,
343 Dwarf_Attribute
*fb_attr_mem
);
345 struct location
*translate_location(struct obstack
*pool
,
346 Dwarf_Attribute
*attr
,
348 Dwarf_Attribute
*fb_attr
,
349 struct location
**tail
,
350 const target_symbol
*e
);
352 bool find_struct_member(const target_symbol::component
& c
,
353 Dwarf_Die
*parentdie
,
354 Dwarf_Die
*memberdie
,
355 std::vector
<Dwarf_Attribute
>& locs
);
357 Dwarf_Die
*translate_components(struct obstack
*pool
,
358 struct location
**tail
,
360 const target_symbol
*e
,
363 Dwarf_Attribute
*attr_mem
);
365 Dwarf_Die
*resolve_unqualified_inner_typedie (Dwarf_Die
*typedie_mem
,
366 Dwarf_Attribute
*attr_mem
,
367 const target_symbol
*e
);
369 void translate_final_fetch_or_store (struct obstack
*pool
,
370 struct location
**tail
,
371 Dwarf_Addr module_bias
,
373 Dwarf_Attribute
*attr_mem
,
375 const target_symbol
*e
,
380 std::string
express_as_string (std::string prelude
,
381 std::string postlude
,
382 struct location
*head
);
384 regex_t blacklist_func
; // function/statement probes
385 regex_t blacklist_func_ret
; // only for .return probes
386 regex_t blacklist_file
; // file name
387 regex_t blacklist_section
; // init/exit sections
388 bool blacklist_enabled
;
389 void build_blacklist();
390 std::string
get_blacklist_section(Dwarf_Addr addr
);
392 // Returns the call frame address operations for the given program counter.
393 Dwarf_Op
*get_cfa_ops (Dwarf_Addr pc
);
399 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */