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>
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
35 // Really old elfutils version, definitely redefine to use old name.
36 #define elf_getshdrstrndx elf_getshstrndx
43 struct inline_instance_info
;
48 enum line_t
{ ABSOLUTE
, RELATIVE
, RANGE
, WILDCARD
};
49 enum info_status
{ info_unknown
, info_present
, info_absent
};
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
;
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()); }
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
67 typedef std::vector
<func_info
> func_info_map_t
;
68 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
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
);
85 symbol_table
*sym_table
;
86 info_status dwarf_status
; // module has dwarf info?
87 info_status symtab_status
; // symbol table cached?
89 void get_symtab(dwarf_query
*q
);
90 void update_symtab(cu_function_cache_t
*funcs
);
92 module_info(const char *name
) :
98 dwarf_status(info_unknown
),
99 symtab_status(info_unknown
)
109 std::map
<std::string
, module_info
*> cache
;
110 bool paths_collected
;
111 bool dwarf_collected
;
113 module_cache() : paths_collected(false), dwarf_collected(false) {}
120 : decl_file(NULL
), decl_line(-1), addr(0), prologue_end(0), weak(false)
122 std::memset(&die
, 0, sizeof(die
));
125 char const * decl_file
;
130 Dwarf_Addr prologue_end
;
135 struct inline_instance_info
137 inline_instance_info()
138 : decl_file(NULL
), decl_line(-1)
140 std::memset(&die
, 0, sizeof(die
));
143 char const * decl_file
;
152 systemtap_session
& sess
;
154 // These are "current" values we focus on.
155 Dwfl_Module
* module
;
156 Dwarf_Addr module_bias
;
157 module_info
* mod_info
;
159 // These describe the current module's PC address range
160 Dwarf_Addr module_start
;
161 Dwarf_Addr module_end
;
165 std::string module_name
;
167 std::string function_name
;
169 dwflpp(systemtap_session
& session
, const std::string
& user_module
="");
172 void get_module_dwarf(bool required
= false, bool report
= true);
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
);
178 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
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
);
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
);
188 void iterate_over_modules(int (* callback
)(Dwfl_Module
*, void **,
189 const char *, Dwarf_Addr
,
193 void iterate_over_cus (int (*callback
)(Dwarf_Die
* die
, void * arg
),
196 bool func_is_inline();
198 void iterate_over_inline_instances (int (* callback
)(Dwarf_Die
* die
, void * arg
),
201 Dwarf_Die
*declaration_resolve(const char *name
);
203 mod_cu_function_cache_t cu_function_cache
;
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);
209 void iterate_over_srcfile_lines (char const * srcfile
,
211 bool need_single_match
,
212 enum line_t line_type
,
213 void (* callback
) (const dwarf_line_t
& line
,
217 void iterate_over_labels (Dwarf_Die
*begin_die
,
219 const char *symfunction
,
221 void (* callback
)(const std::string
&,
228 void collect_srcfiles_matching (std::string
const & pattern
,
229 std::set
<char const *> & filtered_srcfiles
);
231 void resolve_prologue_endings (func_info_map_t
& funcs
);
233 bool function_entrypc (Dwarf_Addr
* addr
);
234 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
);
236 void function_die (Dwarf_Die
*d
);
237 void function_file (char const ** c
);
238 void function_line (int *linep
);
240 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
242 std::string
literal_stmt_for_local (Dwarf_Die
*scope_die
,
244 std::string
const & local
,
245 const target_symbol
*e
,
250 std::string
literal_stmt_for_return (Dwarf_Die
*scope_die
,
252 const target_symbol
*e
,
256 std::string
literal_stmt_for_pointer (Dwarf_Die
*type_die
,
257 const target_symbol
*e
,
261 bool blacklisted_p(const std::string
& funcname
,
262 const std::string
& filename
,
264 const std::string
& module
,
265 const std::string
& section
,
269 Dwarf_Addr
relocate_address(Dwarf_Addr addr
,
270 std::string
& reloc_section
,
271 std::string
& blacklist_section
);
273 Dwarf_Addr
literal_addr_to_sym_addr(Dwarf_Addr lit_addr
);
279 // These are "current" values we focus on.
280 Dwarf
* module_dwarf
;
281 Dwarf_Die
* function
;
283 void setup_kernel(bool debuginfo_needed
= true);
284 void setup_user(const std::string
& module_name
, bool debuginfo_needed
= true);
286 typedef std::map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
287 module_cu_cache_t module_cu_cache
;
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
);
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
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 *),
306 static int cu_function_caching_callback (Dwarf_Die
* func
, void *arg
);
308 bool has_single_line_record (dwarf_query
* q
, char const * srcfile
, int lineno
);
310 static void loc2c_error (void *, const char *fmt
, ...);
312 // This function generates code used for addressing computations of
314 void emit_address (struct obstack
*pool
, Dwarf_Addr address
);
315 static void loc2c_emit_address (void *arg
, struct obstack
*pool
,
318 void print_locals(Dwarf_Die
*die
, std::ostream
&o
);
319 void print_members(Dwarf_Die
*vardie
, std::ostream
&o
);
321 Dwarf_Attribute
*find_variable_and_frame_base (Dwarf_Die
*scope_die
,
323 std::string
const & local
,
324 const target_symbol
*e
,
326 Dwarf_Attribute
*fb_attr_mem
);
328 struct location
*translate_location(struct obstack
*pool
,
329 Dwarf_Attribute
*attr
,
331 Dwarf_Attribute
*fb_attr
,
332 struct location
**tail
,
333 const target_symbol
*e
);
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
);
341 Dwarf_Die
*translate_components(struct obstack
*pool
,
342 struct location
**tail
,
344 const target_symbol
*e
,
347 Dwarf_Attribute
*attr_mem
);
349 Dwarf_Die
*resolve_unqualified_inner_typedie (Dwarf_Die
*typedie_mem
,
350 Dwarf_Attribute
*attr_mem
,
351 const target_symbol
*e
);
353 void translate_final_fetch_or_store (struct obstack
*pool
,
354 struct location
**tail
,
355 Dwarf_Addr module_bias
,
357 Dwarf_Attribute
*attr_mem
,
359 const target_symbol
*e
,
364 std::string
express_as_string (std::string prelude
,
365 std::string postlude
,
366 struct location
*head
);
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
);
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
);
383 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */