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
40 #define write_uleb128(ptr,val) ({ \
41 uint32_t valv = (val); \
44 unsigned char c = valv & 0x7f; \
55 #include <elfutils/libdwfl.h>
60 struct base_func_info
;
62 struct inline_instance_info
;
65 struct external_function_query
;
68 enum lineno_t
{ ABSOLUTE
, RELATIVE
, WILDCARD
, ENUMERATED
};
69 enum info_status
{ info_unknown
, info_present
, info_absent
};
72 typedef std::unordered_map
<Dwarf
*, std::vector
<Dwarf_Die
>*> module_cu_cache_t
;
74 // An instance of this type tracks whether the type units for a given
75 // Dwarf have been read.
76 typedef std::set
<Dwarf
*> module_tus_read_t
;
79 typedef std::unordered_map
<std::string
, Dwarf_Die
> cu_type_cache_t
;
81 // cu die -> (typename -> die)
82 typedef std::unordered_map
<void*, cu_type_cache_t
*> mod_cu_type_cache_t
;
85 typedef std::unordered_multimap
<interned_string
, Dwarf_Die
> cu_function_cache_t
;
87 // cu die -> (function -> die)
88 typedef std::unordered_map
<void*, cu_function_cache_t
*> mod_cu_function_cache_t
;
90 // module -> (function -> die)
91 typedef std::unordered_map
<Dwarf
*, cu_function_cache_t
*> mod_function_cache_t
;
93 // inline function die -> instance die[]
94 typedef std::unordered_map
<void*, std::vector
<Dwarf_Die
>*> cu_inl_function_cache_t
;
96 // function die -> [call site die, call site function die]
97 typedef std::pair
<Dwarf_Die
, Dwarf_Die
> call_site_cache_t
;
98 typedef std::unordered_map
<void*, std::vector
<call_site_cache_t
>*> cu_call_sites_cache_t
;
101 typedef std::unordered_map
<void*, Dwarf_Die
> cu_die_parent_cache_t
;
103 // cu die -> (die -> parent die)
104 typedef std::unordered_map
<void*, cu_die_parent_cache_t
*> mod_cu_die_parent_cache_t
;
106 // Dwarf_Line[] (sorted by lineno)
107 typedef std::vector
<Dwarf_Line
*> lines_t
;
108 typedef std::pair
<lines_t::iterator
,
112 // srcfile -> Dwarf_Line[]
113 typedef std::unordered_map
<std::string
, lines_t
*> srcfile_lines_cache_t
;
115 // cu die -> (srcfile -> Dwarf_Line[])
116 typedef std::unordered_map
<void*, srcfile_lines_cache_t
*> cu_lines_cache_t
;
118 // cu die -> {entry pcs}
119 typedef std::unordered_set
<Dwarf_Addr
> entry_pc_cache_t
;
120 typedef std::unordered_map
<void*, entry_pc_cache_t
*> cu_entry_pc_cache_t
;
122 typedef std::vector
<base_func_info
> base_func_info_map_t
;
123 typedef std::vector
<func_info
> func_info_map_t
;
124 typedef std::vector
<inline_instance_info
> inline_instance_map_t
;
132 std::string elf_path
;
135 symbol_table
*sym_table
;
136 info_status dwarf_status
; // module has dwarf info?
137 info_status symtab_status
; // symbol table cached?
139 std::set
<interned_string
> inlined_funcs
;
140 std::set
<interned_string
> plt_funcs
;
141 std::set
<std::pair
<std::string
,std::string
> > marks
; /* <provider,name> */
144 void update_symtab(cu_function_cache_t
*funcs
);
146 module_info(const char *name
) :
152 dwarf_status(info_unknown
),
153 symtab_status(info_unknown
)
163 std::map
<std::string
, module_info
*> cache
;
164 bool paths_collected
;
165 bool dwarf_collected
;
167 module_cache() : paths_collected(false), dwarf_collected(false) {}
172 struct base_func_info
175 : decl_line(-1), entrypc(0)
177 std::memset(&die
, 0, sizeof(die
));
179 interned_string name
;
180 interned_string decl_file
;
186 struct func_info
: base_func_info
189 : addr(0), prologue_end(0), weak(false), descriptor(false) {}
191 Dwarf_Addr prologue_end
;
192 bool weak
, descriptor
;
196 struct inline_instance_info
: base_func_info
198 inline_instance_info() {}
199 bool operator<(const inline_instance_info
& other
) const;
203 class location_context
;
207 systemtap_session
& sess
;
209 // These are "current" values we focus on.
210 Dwfl_Module
* module
;
211 Dwarf_Addr module_bias
;
212 module_info
* mod_info
;
214 // These describe the current module's PC address range
215 Dwarf_Addr module_start
;
216 Dwarf_Addr module_end
;
220 std::string module_name
;
221 std::string function_name
;
223 dwflpp(systemtap_session
& session
, const std::string
& user_module
, bool kernel_p
, bool debuginfo_needed
= true);
224 dwflpp(systemtap_session
& session
, const std::vector
<std::string
>& user_modules
, bool kernel_p
);
227 void get_module_dwarf(bool required
= false, bool report
= true);
229 void focus_on_module(Dwfl_Module
* m
, module_info
* mi
);
230 void focus_on_cu(Dwarf_Die
* c
);
231 void focus_on_function(Dwarf_Die
* f
);
233 std::string
cu_name(void);
235 Dwarf_Die
*query_cu_containing_address(Dwarf_Addr a
);
237 bool module_name_matches(const std::string
& pattern
);
238 static bool name_has_wildcard(const std::string
& pattern
);
239 bool module_name_final_match(const std::string
& pattern
);
241 bool function_name_matches_pattern(const std::string
& name
, const std::string
& pattern
);
242 bool function_name_matches(const std::string
& pattern
);
243 bool function_scope_matches(const std::vector
<std::string
>& scopes
);
246 void iterate_over_modules(int (* callback
)(Dwfl_Module
*,
253 /* We're using templates here to enforce type-safety between the data arg
254 * we're requested to pass to callback, and the data arg that the callback
255 * actually takes. Rather than putting the implementation here, we simply
256 * call the <void> specialization, which does the real work.
257 * As a result, we need to cast the data arg in the callback signature
258 * and the one passed to void* (which is what elfutils also works with).
260 iterate_over_modules
<void>((int (*)(Dwfl_Module
*,
269 void iterate_over_cus(int (* callback
)(Dwarf_Die
*, T
*),
273 // See comment block in iterate_over_modules()
274 iterate_over_cus
<void>((int (*)(Dwarf_Die
*, void*))callback
,
279 bool func_is_inline();
281 bool func_is_exported();
284 void iterate_over_inline_instances(int (* callback
)(Dwarf_Die
*, T
*),
287 // See comment block in iterate_over_modules()
288 iterate_over_inline_instances
<void>((int (*)(Dwarf_Die
*, void*))callback
,
293 void iterate_over_call_sites(int (* callback
)(Dwarf_Die
*, Dwarf_Die
*, T
*),
296 // See comment block in iterate_over_modules()
297 iterate_over_call_sites
<void>((int (*)(Dwarf_Die
*, Dwarf_Die
*, void*))callback
,
301 std::vector
<Dwarf_Die
> getscopes_die(Dwarf_Die
* die
);
302 std::vector
<Dwarf_Die
> getscopes(Dwarf_Die
* die
);
303 std::vector
<Dwarf_Die
> getscopes(Dwarf_Addr pc
);
305 Dwarf_Die
*declaration_resolve(Dwarf_Die
*type
);
306 Dwarf_Die
*declaration_resolve(const std::string
& name
);
307 Dwarf_Die
*declaration_resolve_other_cus(const std::string
& name
);
310 int iterate_over_functions (int (* callback
)(Dwarf_Die
*, T
*),
311 T
*data
, const std::string
& function
)
313 // See comment block in iterate_over_modules()
314 return iterate_over_functions
<void>((int (*)(Dwarf_Die
*, void*))callback
,
315 (void*)data
, function
);
319 int iterate_single_function (int (* callback
)(Dwarf_Die
*, T
*),
320 T
*data
, const std::string
& function
)
322 // See comment block in iterate_over_modules()
323 return iterate_single_function
<void>((int (*)(Dwarf_Die
*, void*))callback
,
324 (void*)data
, function
);
328 int iterate_over_notes (T
*object
,
329 void (* callback
)(T
*, const std::string
&,
331 int, const char*, size_t))
333 // See comment block in iterate_over_modules()
334 return iterate_over_notes
<void>((void*)object
,
344 void iterate_over_libraries (void (*callback
)(T
*, const char*), T
*data
)
346 // See comment block in iterate_over_modules()
347 iterate_over_libraries
<void>((void (*)(void*,
348 const char*))callback
,
353 int iterate_over_plt (T
*object
, void (*callback
)(T
*, const char*, size_t))
355 // See comment block in iterate_over_modules()
356 return iterate_over_plt
<void>((void*)object
,
363 void iterate_over_srcfile_lines (char const * srcfile
,
364 const std::vector
<int>& linenos
,
365 enum lineno_t lineno_type
,
366 base_func_info_map_t
& funcs
,
367 void (*callback
) (Dwarf_Addr
,
372 // See comment block in iterate_over_modules()
373 iterate_over_srcfile_lines
<void>(srcfile
,
377 (void (*)(Dwarf_Addr
,
378 int, void*))callback
,
384 void iterate_over_labels (Dwarf_Die
*begin_die
,
385 const std::string
& sym
,
386 const base_func_info
& function
,
387 const std::vector
<int>& linenos
,
388 enum lineno_t lineno_type
,
390 void (* callback
)(const base_func_info
&,
398 // See comment block in iterate_over_modules()
399 iterate_over_labels
<void>(begin_die
,
405 (void (*)(const base_func_info
&,
415 void iterate_over_callees (Dwarf_Die
*begin_die
,
416 const std::string
& sym
,
417 int64_t recursion_depth
,
419 void (* callback
)(base_func_info
&,
421 std::stack
<Dwarf_Addr
>*,
423 base_func_info
& caller
,
424 std::stack
<Dwarf_Addr
>*callers
=NULL
)
426 // See comment block in iterate_over_modules()
427 iterate_over_callees
<void>(begin_die
,
431 (void (*)(base_func_info
&,
433 std::stack
<Dwarf_Addr
>*,
440 static int iterate_over_globals (Dwarf_Die
*cu_die
,
441 int (* callback
)(Dwarf_Die
*,
447 // See comment block in iterate_over_modules()
448 return iterate_over_globals
<void>(cu_die
,
456 GElf_Shdr
* get_section(std::string section_name
, GElf_Shdr
*shdr_mem
,
459 void collect_srcfiles_matching (std::string
const & pattern
,
460 std::set
<std::string
> & filtered_srcfiles
);
462 void resolve_prologue_endings (func_info_map_t
& funcs
);
464 bool function_entrypc (Dwarf_Addr
* addr
) __attribute__((warn_unused_result
));
465 bool die_entrypc (Dwarf_Die
* die
, Dwarf_Addr
* addr
) __attribute__((warn_unused_result
));
467 void function_die (Dwarf_Die
*d
);
468 void function_file (char const ** c
);
469 void function_line (int *linep
);
471 bool die_has_pc (Dwarf_Die
& die
, Dwarf_Addr pc
);
472 bool inner_die_containing_pc(Dwarf_Die
& scope
, Dwarf_Addr addr
,
475 bool literal_stmt_for_local (location_context
&ctx
,
476 std::vector
<Dwarf_Die
>& scopes
,
477 std::string
const & local
,
478 const target_symbol
*e
,
481 Dwarf_Die
* type_die_for_local (std::vector
<Dwarf_Die
>& scopes
,
483 std::string
const & local
,
484 const target_symbol
*e
,
488 bool literal_stmt_for_return (location_context
&ctx
,
489 Dwarf_Die
*scope_die
,
490 const target_symbol
*e
,
493 Dwarf_Die
* type_die_for_return (Dwarf_Die
*scope_die
,
495 const target_symbol
*e
,
499 bool literal_stmt_for_pointer (location_context
&ctx
,
501 const target_symbol
*e
,
504 Dwarf_Die
* type_die_for_pointer (Dwarf_Die
*type_die
,
505 const target_symbol
*e
,
509 enum blocklisted_type
510 { blocklisted_none
, // not blocklisted
513 blocklisted_function
,
514 blocklisted_function_return
,
518 blocklisted_type
blocklisted_p(interned_string funcname
,
519 interned_string filename
,
521 interned_string module
,
525 Dwarf_Addr
relocate_address(Dwarf_Addr addr
, interned_string
& reloc_section
);
527 void resolve_unqualified_inner_typedie (Dwarf_Die
*typedie
,
529 const target_symbol
*e
);
531 bool has_gnu_debugdata();
532 bool has_valid_locs();
534 location
*translate_call_site_value (location_context
*ctx
,
535 Dwarf_Attribute
*attr
,
543 // These are "current" values we focus on.
544 Dwarf
* module_dwarf
;
545 Dwarf_Die
* function
;
547 void setup_kernel(const std::string
& module_name
, systemtap_session
&s
, bool debuginfo_needed
= true);
548 void setup_kernel(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
549 void setup_user(const std::vector
<std::string
>& modules
, bool debuginfo_needed
= true);
551 module_cu_cache_t module_cu_cache
;
552 module_tus_read_t module_tus_read
;
553 mod_cu_function_cache_t cu_function_cache
;
554 mod_function_cache_t mod_function_cache
;
556 std::set
<void*> cu_inl_function_cache_done
; // CUs that are already cached
557 cu_inl_function_cache_t cu_inl_function_cache
;
558 void cache_inline_instances (Dwarf_Die
* die
);
560 std::set
<void*> cu_call_sites_cache_done
; // CUs that are already cached
561 cu_call_sites_cache_t cu_call_sites_cache
;
562 void cache_call_sites (Dwarf_Die
* die
, Dwarf_Die
*function
);
564 mod_cu_die_parent_cache_t cu_die_parent_cache
;
565 void cache_die_parents(cu_die_parent_cache_t
* parents
, Dwarf_Die
* die
);
566 cu_die_parent_cache_t
*get_die_parents();
568 // Cache for cu lines sorted by lineno
569 cu_lines_cache_t cu_lines_cache
;
571 // Cache for all entry_pc in each cu
572 cu_entry_pc_cache_t cu_entry_pc_cache
;
573 bool check_cu_entry_pc(Dwarf_Die
*cu
, Dwarf_Addr pc
);
575 Dwarf_Die
* get_parent_scope(Dwarf_Die
* die
);
577 /* The global alias cache is used to resolve any DIE found in a
578 * module that is stubbed out with DW_AT_declaration with a defining
579 * DIE found in a different module. The current assumption is that
580 * this only applies to structures and unions, which have a global
581 * namespace (it deliberately only traverses program scope), so this
582 * cache is indexed by name. If other declaration lookups were
583 * added to it, it would have to be indexed by name and tag
585 mod_cu_type_cache_t global_alias_cache
;
586 static int global_alias_caching_callback(Dwarf_Die
*die
, bool has_inner_types
,
587 const std::string
& prefix
, cu_type_cache_t
*cache
);
588 static int global_alias_caching_callback_cus(Dwarf_Die
*die
, dwflpp
*dw
);
591 static int iterate_over_types (Dwarf_Die
*top_die
,
592 bool has_inner_types
,
593 const std::string
& prefix
,
594 int (* callback
)(Dwarf_Die
*,
600 // See comment block in iterate_over_modules()
601 return iterate_over_types
<void>(top_die
, has_inner_types
, prefix
,
609 static int mod_function_caching_callback (Dwarf_Die
* func
, cu_function_cache_t
*v
);
610 static int cu_function_caching_callback (Dwarf_Die
* func
, cu_function_cache_t
*v
);
612 lines_t
* get_cu_lines_sorted_by_lineno(const char *srcfile
);
614 void collect_lines_for_single_lineno(char const * srcfile
,
617 base_func_info_map_t
& funcs
,
618 lines_t
& matching_lines
);
619 void collect_all_lines(char const * srcfile
,
620 base_func_info_map_t
& funcs
,
621 lines_t
& matching_lines
);
622 std::pair
<int,int> get_nearest_linenos(char const * srcfile
,
624 base_func_info_map_t
& funcs
);
625 int get_nearest_lineno(char const * srcfile
,
627 base_func_info_map_t
& funcs
);
628 void suggest_alternative_linenos(char const * srcfile
,
630 base_func_info_map_t
& funcs
);
632 static int external_function_cu_callback (Dwarf_Die
* cu
, external_function_query
*efq
);
633 static int external_function_func_callback (Dwarf_Die
* func
, external_function_query
*efq
);
635 static void loc2c_error (void *, const char *fmt
, ...) __attribute__ ((noreturn
));
637 // This function generates code used for addressing computations of
639 void emit_address (Dwarf_Addr address
);
641 int dwarf_get_enum (Dwarf_Die
*scopes
, int nscopes
,
642 const char *name
, Dwarf_Die
*result
, Dwarf_Die
*type
);
643 void get_locals(std::vector
<Dwarf_Die
>& scopes
, std::set
<std::string
>& locals
);
644 void get_locals_die(Dwarf_Die
&die
, std::set
<std::string
>& locals
);
645 void get_members(Dwarf_Die
*vardie
, std::set
<std::string
>& members
,
646 std::set
<std::string
> &dupes
);
648 Dwarf_Attribute
*find_variable_and_frame_base (std::vector
<Dwarf_Die
>& scopes
,
650 std::string
const & local
,
651 const target_symbol
*e
,
654 Dwarf_Attribute
*fb_attr_mem
,
657 std::string
die_location_as_string(Dwarf_Die
*);
658 std::string
pc_location_as_function_string(Dwarf_Addr
);
659 std::string
pc_die_line_string(Dwarf_Addr
, Dwarf_Die
*);
661 /* source file name, line and column info for pc in current cu. */
662 const char *pc_line (Dwarf_Addr
, int *, int *);
664 location
*translate_location(location_context
*ctx
,
665 Dwarf_Attribute
*attr
,
668 Dwarf_Attribute
*fb_attr
,
669 const target_symbol
*e
,
672 bool find_struct_member(const target_symbol::component
& c
,
673 Dwarf_Die
*parentdie
,
674 Dwarf_Die
*memberdie
,
675 std::vector
<Dwarf_Die
>& dies
,
676 std::vector
<Dwarf_Attribute
>& locs
);
678 void translate_components(location_context
*ctx
,
680 const target_symbol
*e
,
686 void translate_base_ref (location_context
&ctx
, Dwarf_Word byte_size
,
687 bool signed_p
, bool lvalue_p
);
688 void translate_bitfield(location_context
&ctx
, Dwarf_Word byte_size
,
689 Dwarf_Word bit_offset
, Dwarf_Word bit_size
,
691 void translate_final_fetch_or_store (location_context
&ctx
,
696 void translate_pointer(location_context
&ctx
, Dwarf_Die
*typedie
,
699 regex_t blocklist_func
; // function/statement probes
700 regex_t blocklist_func_ret
; // only for .return probes
701 regex_t blocklist_file
; // file name
702 regex_t blocklist_section
; // init/exit sections
703 bool blocklist_enabled
;
704 void build_kernel_blocklist();
705 void build_user_blocklist();
706 std::string
get_blocklist_section(Dwarf_Addr addr
);
708 // Returns the call frame address operations for the given program counter.
709 Dwarf_Op
*get_cfa_ops (Dwarf_Addr pc
);
711 Dwarf_Addr
vardie_from_symtable(Dwarf_Die
*vardie
, Dwarf_Addr
*addr
);
713 static int add_module_build_id_to_hash (Dwfl_Module
*m
,
714 void **userdata
__attribute__ ((unused
)),
719 static bool is_gcc_producer(Dwarf_Die
*cudie
, std::string
& producer
,
720 std::string
& version
);
723 Dwarf_Addr
pr15123_retry_addr (Dwarf_Addr pc
, Dwarf_Die
* var
);
726 // Template <void> specializations for iterate_over_* functions
729 dwflpp::iterate_over_modules
<void>(int (*callback
)(Dwfl_Module
*,
736 dwflpp::iterate_over_cus
<void>(int (*callback
)(Dwarf_Die
*, void*),
740 dwflpp::iterate_over_inline_instances
<void>(int (*callback
)(Dwarf_Die
*, void*),
743 dwflpp::iterate_over_call_sites
<void>(int (*callback
)(Dwarf_Die
*, Dwarf_Die
*, void*),
746 dwflpp::iterate_over_functions
<void>(int (*callback
)(Dwarf_Die
*, void*),
747 void *data
, const std::string
& function
);
749 dwflpp::iterate_single_function
<void>(int (*callback
)(Dwarf_Die
*, void*),
750 void *data
, const std::string
& function
);
752 dwflpp::iterate_over_globals
<void>(Dwarf_Die
*cu_die
,
753 int (*callback
)(Dwarf_Die
*,
759 dwflpp::iterate_over_types
<void>(Dwarf_Die
*top_die
,
760 bool has_inner_types
,
761 const std::string
& prefix
,
762 int (* callback
)(Dwarf_Die
*,
768 dwflpp::iterate_over_notes
<void>(void *object
, void (*callback
)(void*,
775 dwflpp::iterate_over_libraries
<void>(void (*callback
)(void*, const char*),
778 dwflpp::iterate_over_plt
<void>(void *object
, void (*callback
)(void*,
782 dwflpp::iterate_over_srcfile_lines
<void>(char const * srcfile
,
783 const std::vector
<int>& linenos
,
784 enum lineno_t lineno_type
,
785 base_func_info_map_t
& funcs
,
786 void (* callback
) (Dwarf_Addr
,
791 dwflpp::iterate_over_labels
<void>(Dwarf_Die
*begin_die
,
792 const std::string
& sym
,
793 const base_func_info
& function
,
794 const std::vector
<int>& linenos
,
795 enum lineno_t lineno_type
,
797 void (* callback
)(const base_func_info
&,
805 dwflpp::iterate_over_callees
<void>(Dwarf_Die
*begin_die
,
806 const std::string
& sym
,
807 int64_t recursion_depth
,
809 void (* callback
)(base_func_info
&,
811 std::stack
<Dwarf_Addr
>*,
813 base_func_info
& caller
,
814 std::stack
<Dwarf_Addr
> *callers
);
818 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */