1 // C++ interface to dwfl
2 // Copyright (C) 2005-2019 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 "setupdwfl.h"
19 #include "stringtable.h"
26 #include <unordered_map>
27 #include <unordered_set>
30 // Old elf.h doesn't know about this machine type.
32 #define EM_AARCH64 183
37 #include <elfutils/libdwfl.h>
42 struct base_func_info
;
44 struct inline_instance_info
;
47 struct external_function_query
;
50 enum lineno_t
{ ABSOLUTE
, RELATIVE
, WILDCARD
, ENUMERATED
};
51 enum info_status
{ info_unknown
, info_present
, info_absent
};
54 typedef std::unordered_map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
56 // An instance of this type tracks whether the type units for a given
57 // Dwarf have been read.
58 typedef std::set
<Dwarf
*> module_tus_read_t
;
61 typedef std::unordered_map
<std::string
, Dwarf_Die
> cu_type_cache_t
;
63 // cu die -> (typename -> die)
64 typedef std::unordered_map
<void*, cu_type_cache_t
*> mod_cu_type_cache_t
;
67 typedef std::unordered_multimap
<interned_string
, Dwarf_Die
> cu_function_cache_t
;
69 // cu die -> (function -> die)
70 typedef std::unordered_map
<void*, cu_function_cache_t
*> mod_cu_function_cache_t
;
72 // module -> (function -> die)
73 typedef std::unordered_map
<Dwarf
*, cu_function_cache_t
*> mod_function_cache_t
;
75 // inline function die -> instance die[]
76 typedef std::unordered_map
<void*, std::vector
<Dwarf_Die
>*> cu_inl_function_cache_t
;
78 // function die -> [call site die, call site function die]
79 typedef std::pair
<Dwarf_Die
, Dwarf_Die
> call_site_cache_t
;
80 typedef std::unordered_map
<void*, std::vector
<call_site_cache_t
>*> cu_call_sites_cache_t
;
83 typedef std::unordered_map
<void*, Dwarf_Die
> cu_die_parent_cache_t
;
85 // cu die -> (die -> parent die)
86 typedef std::unordered_map
<void*, cu_die_parent_cache_t
*> mod_cu_die_parent_cache_t
;
88 // Dwarf_Line[] (sorted by lineno)
89 typedef std::vector
<Dwarf_Line
*> lines_t
;
90 typedef std::pair
<lines_t::iterator
,
94 // srcfile -> Dwarf_Line[]
95 typedef std::unordered_map
<std::string
, lines_t
*> srcfile_lines_cache_t
;
97 // cu die -> (srcfile -> Dwarf_Line[])
98 typedef std::unordered_map
<void*, srcfile_lines_cache_t
*> cu_lines_cache_t
;
100 // cu die -> {entry pcs}
101 typedef std::unordered_set
<Dwarf_Addr
> entry_pc_cache_t
;
102 typedef std::unordered_map
<void*, entry_pc_cache_t
*> cu_entry_pc_cache_t
;
104 typedef std::vector
<base_func_info
> base_func_info_map_t
;
105 typedef std::vector
<func_info
> func_info_map_t
;
106 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
114 std::string elf_path
;
117 symbol_table
*sym_table
;
118 info_status dwarf_status
; // module has dwarf info?
119 info_status symtab_status
; // symbol table cached?
121 std::set
<interned_string
> inlined_funcs
;
122 std::set
<interned_string
> plt_funcs
;
123 std::set
<std::pair
<std::string
,std::string
> > marks
; /* <provider,name> */
126 void update_symtab(cu_function_cache_t
*funcs
);
128 module_info(const char *name
) :
134 dwarf_status(info_unknown
),
135 symtab_status(info_unknown
)
145 std::map
<std::string
, module_info
*> cache
;
146 bool paths_collected
;
147 bool dwarf_collected
;
149 module_cache() : paths_collected(false), dwarf_collected(false) {}
154 struct base_func_info
157 : decl_line(-1), entrypc(0)
159 std::memset(&die
, 0, sizeof(die
));
161 interned_string name
;
162 interned_string decl_file
;
168 struct func_info
: base_func_info
171 : addr(0), prologue_end(0), weak(false), descriptor(false) {}
173 Dwarf_Addr prologue_end
;
174 bool weak
, descriptor
;
178 struct inline_instance_info
: base_func_info
180 inline_instance_info() {}
181 bool operator<(const inline_instance_info
& other
) const;
185 struct location_context
;
189 systemtap_session
& sess
;
191 // These are "current" values we focus on.
192 Dwfl_Module
* module
;
193 Dwarf_Addr module_bias
;
194 module_info
* mod_info
;
196 // These describe the current module's PC address range
197 Dwarf_Addr module_start
;
198 Dwarf_Addr module_end
;
202 std::string module_name
;
203 std::string function_name
;
205 dwflpp(systemtap_session
& session
, const std::string
& user_module
, bool kernel_p
);
206 dwflpp(systemtap_session
& session
, const std::vector
<std::string
>& user_modules
, bool kernel_p
);
209 void get_module_dwarf(bool required
= false, bool report
= true);
211 void focus_on_module(Dwfl_Module
* m
, module_info
* mi
);
212 void focus_on_cu(Dwarf_Die
* c
);
213 void focus_on_function(Dwarf_Die
* f
);
215 std::string
cu_name(void);
217 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
219 bool module_name_matches(const std::string
& pattern
);
220 static bool name_has_wildcard(const std::string
& pattern
);
221 bool module_name_final_match(const std::string
& pattern
);
223 bool function_name_matches_pattern(const std::string
& name
, const std::string
& pattern
);
224 bool function_name_matches(const std::string
& pattern
);
225 bool function_scope_matches(const std::vector
<std::string
>& scopes
);
228 void iterate_over_modules(int (* callback
)(Dwfl_Module
*,
235 /* We're using templates here to enforce type-safety between the data arg
236 * we're requested to pass to callback, and the data arg that the callback
237 * actually takes. Rather than putting the implementation here, we simply
238 * call the <void> specialization, which does the real work.
239 * As a result, we need to cast the data arg in the callback signature
240 * and the one passed to void* (which is what elfutils also works with).
242 iterate_over_modules
<void>((int (*)(Dwfl_Module
*,
251 void iterate_over_cus(int (* callback
)(Dwarf_Die
*, T
*),
255 // See comment block in iterate_over_modules()
256 iterate_over_cus
<void>((int (*)(Dwarf_Die
*, void*))callback
,
261 bool func_is_inline();
263 bool func_is_exported();
266 void iterate_over_inline_instances(int (* callback
)(Dwarf_Die
*, T
*),
269 // See comment block in iterate_over_modules()
270 iterate_over_inline_instances
<void>((int (*)(Dwarf_Die
*, void*))callback
,
275 void iterate_over_call_sites(int (* callback
)(Dwarf_Die
*, Dwarf_Die
*, T
*),
278 // See comment block in iterate_over_modules()
279 iterate_over_call_sites
<void>((int (*)(Dwarf_Die
*, Dwarf_Die
*, void*))callback
,
283 std::vector
<Dwarf_Die
> getscopes_die(Dwarf_Die
* die
);
284 std::vector
<Dwarf_Die
> getscopes(Dwarf_Die
* die
);
285 std::vector
<Dwarf_Die
> getscopes(Dwarf_Addr pc
);
287 Dwarf_Die
*declaration_resolve(Dwarf_Die
*type
);
288 Dwarf_Die
*declaration_resolve(const std::string
& name
);
289 Dwarf_Die
*declaration_resolve_other_cus(const std::string
& name
);
292 int iterate_over_functions (int (* callback
)(Dwarf_Die
*, T
*),
293 T
*data
, const std::string
& function
)
295 // See comment block in iterate_over_modules()
296 return iterate_over_functions
<void>((int (*)(Dwarf_Die
*, void*))callback
,
297 (void*)data
, function
);
301 int iterate_single_function (int (* callback
)(Dwarf_Die
*, T
*),
302 T
*data
, const std::string
& function
)
304 // See comment block in iterate_over_modules()
305 return iterate_single_function
<void>((int (*)(Dwarf_Die
*, void*))callback
,
306 (void*)data
, function
);
310 int iterate_over_notes (T
*object
,
311 void (* callback
)(T
*, const std::string
&,
313 int, const char*, size_t))
315 // See comment block in iterate_over_modules()
316 return iterate_over_notes
<void>((void*)object
,
326 void iterate_over_libraries (void (*callback
)(T
*, const char*), T
*data
)
328 // See comment block in iterate_over_modules()
329 iterate_over_libraries
<void>((void (*)(void*,
330 const char*))callback
,
335 int iterate_over_plt (T
*object
, void (*callback
)(T
*, const char*, size_t))
337 // See comment block in iterate_over_modules()
338 return iterate_over_plt
<void>((void*)object
,
345 void iterate_over_srcfile_lines (char const * srcfile
,
346 const std::vector
<int>& linenos
,
347 enum lineno_t lineno_type
,
348 base_func_info_map_t
& funcs
,
349 void (*callback
) (Dwarf_Addr
,
354 // See comment block in iterate_over_modules()
355 iterate_over_srcfile_lines
<void>(srcfile
,
359 (void (*)(Dwarf_Addr
,
360 int, void*))callback
,
366 void iterate_over_labels (Dwarf_Die
*begin_die
,
367 const std::string
& sym
,
368 const base_func_info
& function
,
369 const std::vector
<int>& linenos
,
370 enum lineno_t lineno_type
,
372 void (* callback
)(const base_func_info
&,
380 // See comment block in iterate_over_modules()
381 iterate_over_labels
<void>(begin_die
,
387 (void (*)(const base_func_info
&,
397 void iterate_over_callees (Dwarf_Die
*begin_die
,
398 const std::string
& sym
,
399 int64_t recursion_depth
,
401 void (* callback
)(base_func_info
&,
403 std::stack
<Dwarf_Addr
>*,
405 base_func_info
& caller
,
406 std::stack
<Dwarf_Addr
>*callers
=NULL
)
408 // See comment block in iterate_over_modules()
409 iterate_over_callees
<void>(begin_die
,
413 (void (*)(base_func_info
&,
415 std::stack
<Dwarf_Addr
>*,
422 static int iterate_over_globals (Dwarf_Die
*cu_die
,
423 int (* callback
)(Dwarf_Die
*,
429 // See comment block in iterate_over_modules()
430 return iterate_over_globals
<void>(cu_die
,
438 GElf_Shdr
* get_section(std::string section_name
, GElf_Shdr
*shdr_mem
,
441 void collect_srcfiles_matching (std::string
const & pattern
,
442 std::set
<std::string
> & filtered_srcfiles
);
444 void resolve_prologue_endings (func_info_map_t
& funcs
);
446 bool function_entrypc (Dwarf_Addr
* addr
) __attribute__((warn_unused_result
));
447 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
) __attribute__((warn_unused_result
));
449 void function_die (Dwarf_Die
*d
);
450 void function_file (char const ** c
);
451 void function_line (int *linep
);
453 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
454 bool inner_die_containing_pc(Dwarf_Die
& scope
, Dwarf_Addr addr
,
457 bool literal_stmt_for_local (location_context
&ctx
,
458 std::vector
<Dwarf_Die
>& scopes
,
459 std::string
const & local
,
460 const target_symbol
*e
,
463 Dwarf_Die
* type_die_for_local (std::vector
<Dwarf_Die
>& scopes
,
465 std::string
const & local
,
466 const target_symbol
*e
,
470 bool literal_stmt_for_return (location_context
&ctx
,
471 Dwarf_Die
*scope_die
,
472 const target_symbol
*e
,
475 Dwarf_Die
* type_die_for_return (Dwarf_Die
*scope_die
,
477 const target_symbol
*e
,
481 bool literal_stmt_for_pointer (location_context
&ctx
,
483 const target_symbol
*e
,
486 Dwarf_Die
* type_die_for_pointer (Dwarf_Die
*type_die
,
487 const target_symbol
*e
,
491 enum blacklisted_type
492 { blacklisted_none
, // not blacklisted
495 blacklisted_function
,
496 blacklisted_function_return
,
500 blacklisted_type
blacklisted_p(interned_string funcname
,
501 interned_string filename
,
503 interned_string module
,
507 Dwarf_Addr
relocate_address(Dwarf_Addr addr
, interned_string
& reloc_section
);
509 void resolve_unqualified_inner_typedie (Dwarf_Die
*typedie
,
511 const target_symbol
*e
);
513 bool has_gnu_debugdata();
514 bool has_valid_locs();
516 location
*translate_call_site_value (location_context
*ctx
,
517 Dwarf_Attribute
*attr
,
525 // These are "current" values we focus on.
526 Dwarf
* module_dwarf
;
527 Dwarf_Die
* function
;
529 void setup_kernel(const std::string
& module_name
, systemtap_session
&s
, bool debuginfo_needed
= true);
530 void setup_kernel(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
531 void setup_user(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
533 module_cu_cache_t module_cu_cache
;
534 module_tus_read_t module_tus_read
;
535 mod_cu_function_cache_t cu_function_cache
;
536 mod_function_cache_t mod_function_cache
;
538 std::set
<void*> cu_inl_function_cache_done
; // CUs that are already cached
539 cu_inl_function_cache_t cu_inl_function_cache
;
540 void cache_inline_instances (Dwarf_Die
* die
);
542 std::set
<void*> cu_call_sites_cache_done
; // CUs that are already cached
543 cu_call_sites_cache_t cu_call_sites_cache
;
544 void cache_call_sites (Dwarf_Die
* die
, Dwarf_Die
*function
);
546 mod_cu_die_parent_cache_t cu_die_parent_cache
;
547 void cache_die_parents(cu_die_parent_cache_t
* parents
, Dwarf_Die
* die
);
548 cu_die_parent_cache_t
*get_die_parents();
550 // Cache for cu lines sorted by lineno
551 cu_lines_cache_t cu_lines_cache
;
553 // Cache for all entry_pc in each cu
554 cu_entry_pc_cache_t cu_entry_pc_cache
;
555 bool check_cu_entry_pc(Dwarf_Die
*cu
, Dwarf_Addr pc
);
557 Dwarf_Die
* get_parent_scope(Dwarf_Die
* die
);
559 /* The global alias cache is used to resolve any DIE found in a
560 * module that is stubbed out with DW_AT_declaration with a defining
561 * DIE found in a different module. The current assumption is that
562 * this only applies to structures and unions, which have a global
563 * namespace (it deliberately only traverses program scope), so this
564 * cache is indexed by name. If other declaration lookups were
565 * added to it, it would have to be indexed by name and tag
567 mod_cu_type_cache_t global_alias_cache
;
568 static int global_alias_caching_callback(Dwarf_Die
*die
, bool has_inner_types
,
569 const std::string
& prefix
, cu_type_cache_t
*cache
);
570 static int global_alias_caching_callback_cus(Dwarf_Die
*die
, dwflpp
*dw
);
573 static int iterate_over_types (Dwarf_Die
*top_die
,
574 bool has_inner_types
,
575 const std::string
& prefix
,
576 int (* callback
)(Dwarf_Die
*,
582 // See comment block in iterate_over_modules()
583 return iterate_over_types
<void>(top_die
, has_inner_types
, prefix
,
591 static int mod_function_caching_callback (Dwarf_Die
* func
, cu_function_cache_t
*v
);
592 static int cu_function_caching_callback (Dwarf_Die
* func
, cu_function_cache_t
*v
);
594 lines_t
* get_cu_lines_sorted_by_lineno(const char *srcfile
);
596 void collect_lines_for_single_lineno(char const * srcfile
,
599 base_func_info_map_t
& funcs
,
600 lines_t
& matching_lines
);
601 void collect_all_lines(char const * srcfile
,
602 base_func_info_map_t
& funcs
,
603 lines_t
& matching_lines
);
604 std::pair
<int,int> get_nearest_linenos(char const * srcfile
,
606 base_func_info_map_t
& funcs
);
607 int get_nearest_lineno(char const * srcfile
,
609 base_func_info_map_t
& funcs
);
610 void suggest_alternative_linenos(char const * srcfile
,
612 base_func_info_map_t
& funcs
);
614 static int external_function_cu_callback (Dwarf_Die
* cu
, external_function_query
*efq
);
615 static int external_function_func_callback (Dwarf_Die
* func
, external_function_query
*efq
);
617 static void loc2c_error (void *, const char *fmt
, ...) __attribute__ ((noreturn
));
619 // This function generates code used for addressing computations of
621 void emit_address (Dwarf_Addr address
);
623 void get_locals(std::vector
<Dwarf_Die
>& scopes
, std::set
<std::string
>& locals
);
624 void get_locals_die(Dwarf_Die
&die
, std::set
<std::string
>& locals
);
625 void get_members(Dwarf_Die
*vardie
, std::set
<std::string
>& members
,
626 std::set
<std::string
> &dupes
);
628 Dwarf_Attribute
*find_variable_and_frame_base (std::vector
<Dwarf_Die
>& scopes
,
630 std::string
const & local
,
631 const target_symbol
*e
,
633 Dwarf_Attribute
*fb_attr_mem
,
636 std::string
die_location_as_string(Dwarf_Die
*);
637 std::string
pc_location_as_function_string(Dwarf_Addr
);
638 std::string
pc_die_line_string(Dwarf_Addr
, Dwarf_Die
*);
640 /* source file name, line and column info for pc in current cu. */
641 const char *pc_line (Dwarf_Addr
, int *, int *);
643 location
*translate_location(location_context
*ctx
,
644 Dwarf_Attribute
*attr
,
647 Dwarf_Attribute
*fb_attr
,
648 const target_symbol
*e
,
651 bool find_struct_member(const target_symbol::component
& c
,
652 Dwarf_Die
*parentdie
,
653 Dwarf_Die
*memberdie
,
654 std::vector
<Dwarf_Die
>& dies
,
655 std::vector
<Dwarf_Attribute
>& locs
);
657 void translate_components(location_context
*ctx
,
659 const target_symbol
*e
,
665 void translate_base_ref (location_context
&ctx
, Dwarf_Word byte_size
,
666 bool signed_p
, bool lvalue_p
);
667 void translate_bitfield(location_context
&ctx
, Dwarf_Word byte_size
,
668 Dwarf_Word bit_offset
, Dwarf_Word bit_size
,
670 void translate_final_fetch_or_store (location_context
&ctx
,
675 void translate_pointer(location_context
&ctx
, Dwarf_Die
*typedie
,
678 regex_t blacklist_func
; // function/statement probes
679 regex_t blacklist_func_ret
; // only for .return probes
680 regex_t blacklist_file
; // file name
681 regex_t blacklist_section
; // init/exit sections
682 bool blacklist_enabled
;
683 void build_kernel_blacklist();
684 void build_user_blacklist();
685 std::string
get_blacklist_section(Dwarf_Addr addr
);
687 // Returns the call frame address operations for the given program counter.
688 Dwarf_Op
*get_cfa_ops (Dwarf_Addr pc
);
690 Dwarf_Addr
vardie_from_symtable(Dwarf_Die
*vardie
, Dwarf_Addr
*addr
);
692 static int add_module_build_id_to_hash (Dwfl_Module
*m
,
693 void **userdata
__attribute__ ((unused
)),
698 static bool is_gcc_producer(Dwarf_Die
*cudie
, std::string
& producer
,
699 std::string
& version
);
702 Dwarf_Addr
pr15123_retry_addr (Dwarf_Addr pc
, Dwarf_Die
* var
);
705 // Template <void> specializations for iterate_over_* functions
708 dwflpp::iterate_over_modules
<void>(int (*callback
)(Dwfl_Module
*,
715 dwflpp::iterate_over_cus
<void>(int (*callback
)(Dwarf_Die
*, void*),
719 dwflpp::iterate_over_inline_instances
<void>(int (*callback
)(Dwarf_Die
*, void*),
722 dwflpp::iterate_over_call_sites
<void>(int (*callback
)(Dwarf_Die
*, Dwarf_Die
*, void*),
725 dwflpp::iterate_over_functions
<void>(int (*callback
)(Dwarf_Die
*, void*),
726 void *data
, const std::string
& function
);
728 dwflpp::iterate_single_function
<void>(int (*callback
)(Dwarf_Die
*, void*),
729 void *data
, const std::string
& function
);
731 dwflpp::iterate_over_globals
<void>(Dwarf_Die
*cu_die
,
732 int (*callback
)(Dwarf_Die
*,
738 dwflpp::iterate_over_types
<void>(Dwarf_Die
*top_die
,
739 bool has_inner_types
,
740 const std::string
& prefix
,
741 int (* callback
)(Dwarf_Die
*,
747 dwflpp::iterate_over_notes
<void>(void *object
, void (*callback
)(void*,
754 dwflpp::iterate_over_libraries
<void>(void (*callback
)(void*, const char*),
757 dwflpp::iterate_over_plt
<void>(void *object
, void (*callback
)(void*,
761 dwflpp::iterate_over_srcfile_lines
<void>(char const * srcfile
,
762 const std::vector
<int>& linenos
,
763 enum lineno_t lineno_type
,
764 base_func_info_map_t
& funcs
,
765 void (* callback
) (Dwarf_Addr
,
770 dwflpp::iterate_over_labels
<void>(Dwarf_Die
*begin_die
,
771 const std::string
& sym
,
772 const base_func_info
& function
,
773 const std::vector
<int>& linenos
,
774 enum lineno_t lineno_type
,
776 void (* callback
)(const base_func_info
&,
784 dwflpp::iterate_over_callees
<void>(Dwarf_Die
*begin_die
,
785 const std::string
& sym
,
786 int64_t recursion_depth
,
788 void (* callback
)(base_func_info
&,
790 std::stack
<Dwarf_Addr
>*,
792 base_func_info
& caller
,
793 std::stack
<Dwarf_Addr
> *callers
);
797 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */