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"
27 #include <elfutils/libdwfl.h>
31 #if !_ELFUTILS_PREREQ(0,142)
32 // Always use newer name, old name is deprecated in 0.142.
33 #define elf_getshdrstrndx elf_getshstrndx
38 struct inline_instance_info
;
43 enum line_t
{ ABSOLUTE
, RELATIVE
, RANGE
, WILDCARD
};
44 enum info_status
{ info_unknown
, info_present
, info_absent
};
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
;
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()); }
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
62 typedef std::vector
<func_info
> func_info_map_t
;
63 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
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
);
80 symbol_table
*sym_table
;
81 info_status dwarf_status
; // module has dwarf info?
82 info_status symtab_status
; // symbol table cached?
84 void get_symtab(dwarf_query
*q
);
85 void update_symtab(cu_function_cache_t
*funcs
);
87 module_info(const char *name
) :
93 dwarf_status(info_unknown
),
94 symtab_status(info_unknown
)
104 std::map
<std::string
, module_info
*> cache
;
105 bool paths_collected
;
106 bool dwarf_collected
;
108 module_cache() : paths_collected(false), dwarf_collected(false) {}
115 : decl_file(NULL
), decl_line(-1), addr(0), prologue_end(0), weak(false)
117 std::memset(&die
, 0, sizeof(die
));
120 char const * decl_file
;
125 Dwarf_Addr prologue_end
;
130 struct inline_instance_info
132 inline_instance_info()
133 : decl_file(NULL
), decl_line(-1)
135 std::memset(&die
, 0, sizeof(die
));
138 char const * decl_file
;
147 systemtap_session
& sess
;
149 // These are "current" values we focus on.
150 Dwfl_Module
* module
;
151 Dwarf_Addr module_bias
;
152 module_info
* mod_info
;
154 // These describe the current module's PC address range
155 Dwarf_Addr module_start
;
156 Dwarf_Addr module_end
;
160 std::string module_name
;
162 std::string function_name
;
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
);
168 void get_module_dwarf(bool required
= false, bool report
= true);
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
);
174 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
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
);
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
);
184 void iterate_over_modules(int (* callback
)(Dwfl_Module
*, void **,
185 const char *, Dwarf_Addr
,
189 void iterate_over_cus (int (*callback
)(Dwarf_Die
* die
, void * arg
),
192 bool func_is_inline();
194 void iterate_over_inline_instances (int (* callback
)(Dwarf_Die
* die
, void * arg
),
197 Dwarf_Die
*declaration_resolve(const char *name
);
199 mod_cu_function_cache_t cu_function_cache
;
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);
205 void iterate_over_srcfile_lines (char const * srcfile
,
207 bool need_single_match
,
208 enum line_t line_type
,
209 void (* callback
) (const dwarf_line_t
& line
,
211 const std::string
& func_pattern
,
214 void iterate_over_labels (Dwarf_Die
*begin_die
,
216 const char *symfunction
,
218 void (* callback
)(const std::string
&,
225 void collect_srcfiles_matching (std::string
const & pattern
,
226 std::set
<char const *> & filtered_srcfiles
);
228 void resolve_prologue_endings (func_info_map_t
& funcs
);
230 bool function_entrypc (Dwarf_Addr
* addr
);
231 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
);
233 void function_die (Dwarf_Die
*d
);
234 void function_file (char const ** c
);
235 void function_line (int *linep
);
237 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
239 std::string
literal_stmt_for_local (Dwarf_Die
*scope_die
,
241 std::string
const & local
,
242 const target_symbol
*e
,
247 std::string
literal_stmt_for_return (Dwarf_Die
*scope_die
,
249 const target_symbol
*e
,
253 std::string
literal_stmt_for_pointer (Dwarf_Die
*type_die
,
254 const target_symbol
*e
,
258 bool blacklisted_p(const std::string
& funcname
,
259 const std::string
& filename
,
261 const std::string
& module
,
262 const std::string
& section
,
266 Dwarf_Addr
relocate_address(Dwarf_Addr addr
,
267 std::string
& reloc_section
,
268 std::string
& blacklist_section
);
270 Dwarf_Addr
literal_addr_to_sym_addr(Dwarf_Addr lit_addr
);
276 // These are "current" values we focus on.
277 Dwarf
* module_dwarf
;
278 Dwarf_Die
* function
;
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);
283 typedef std::map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
284 module_cu_cache_t module_cu_cache
;
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
);
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
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 *),
303 static int cu_function_caching_callback (Dwarf_Die
* func
, void *arg
);
305 bool has_single_line_record (dwarf_query
* q
, char const * srcfile
, int lineno
);
307 static void loc2c_error (void *, const char *fmt
, ...);
309 // This function generates code used for addressing computations of
311 void emit_address (struct obstack
*pool
, Dwarf_Addr address
);
312 static void loc2c_emit_address (void *arg
, struct obstack
*pool
,
315 void print_locals(Dwarf_Die
*die
, std::ostream
&o
);
316 void print_members(Dwarf_Die
*vardie
, std::ostream
&o
);
318 Dwarf_Attribute
*find_variable_and_frame_base (Dwarf_Die
*scope_die
,
320 std::string
const & local
,
321 const target_symbol
*e
,
323 Dwarf_Attribute
*fb_attr_mem
);
325 struct location
*translate_location(struct obstack
*pool
,
326 Dwarf_Attribute
*attr
,
328 Dwarf_Attribute
*fb_attr
,
329 struct location
**tail
,
330 const target_symbol
*e
);
332 bool find_struct_member(const target_symbol::component
& c
,
333 Dwarf_Die
*parentdie
,
334 Dwarf_Die
*memberdie
,
335 std::vector
<Dwarf_Attribute
>& locs
);
337 Dwarf_Die
*translate_components(struct obstack
*pool
,
338 struct location
**tail
,
340 const target_symbol
*e
,
343 Dwarf_Attribute
*attr_mem
);
345 Dwarf_Die
*resolve_unqualified_inner_typedie (Dwarf_Die
*typedie_mem
,
346 Dwarf_Attribute
*attr_mem
,
347 const target_symbol
*e
);
349 void translate_final_fetch_or_store (struct obstack
*pool
,
350 struct location
**tail
,
351 Dwarf_Addr module_bias
,
353 Dwarf_Attribute
*attr_mem
,
355 const target_symbol
*e
,
360 std::string
express_as_string (std::string prelude
,
361 std::string postlude
,
362 struct location
*head
);
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
);
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
);
376 // Returns the call frame address operations for the given program counter.
377 Dwarf_Op
*get_cfa_ops (Dwarf_Addr pc
);
383 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */