libabigail
Loading...
Searching...
No Matches
abg-dwarf-reader.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2013-2023 Red Hat, Inc.
5//
6// Author: Dodji Seketeli
7
8/// @file
9///
10/// This file contains the definitions of the entry points to
11/// de-serialize an instance of @ref abigail::corpus from a file in
12/// elf format, containing dwarf information.
13
14#include "abg-internal.h"
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <unistd.h>
19#include <libgen.h>
20#include <assert.h>
21#include <limits.h>
22#include <elfutils/libdwfl.h>
23#include <dwarf.h>
24#include <algorithm>
25#include <cmath>
26#include <cstring>
27#include <deque>
28#include <list>
29#include <memory>
30#include <ostream>
31#include <sstream>
32#include <stack>
33#include <unordered_map>
34#include <unordered_set>
35#include <map>
36
37#include "abg-ir-priv.h"
39#include "abg-corpus-priv.h"
40#include "abg-symtab-reader.h"
41
42// <headers defining libabigail's API go under here>
43ABG_BEGIN_EXPORT_DECLARATIONS
44
45#include "abg-dwarf-reader.h"
47#include "abg-sptr-utils.h"
48#include "abg-tools-utils.h"
49#include "abg-elf-helpers.h"
50
51ABG_END_EXPORT_DECLARATIONS
52// </headers defining libabigail's API>
53
54#ifndef UINT64_MAX
55#define UINT64_MAX 0xffffffffffffffff
56#endif
57
58using std::string;
59
60namespace abigail
61{
62
63using std::cerr;
64
65/// The namespace for the DWARF reader.
66namespace dwarf
67{
68
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71using std::unordered_map;
72using std::unordered_set;
73using std::stack;
74using std::deque;
75using std::list;
76using std::map;
78
79using namespace elf_helpers; // TODO: avoid using namespace
80
81/// Where a DIE comes from. For instance, a DIE can come from the main
82/// debug info section, the alternate debug info section or from the
83/// type unit section.
85{
86 NO_DEBUG_INFO_DIE_SOURCE,
87 PRIMARY_DEBUG_INFO_DIE_SOURCE,
88 ALT_DEBUG_INFO_DIE_SOURCE,
89 TYPE_UNIT_DIE_SOURCE,
90 NUMBER_OF_DIE_SOURCES, // This one must always be the latest
91 // enumerator
92};
93
94
95/// A convenience typedef for a vector of Dwarf_Off.
96typedef vector<Dwarf_Off> dwarf_offsets_type;
97
98/// Convenience typedef for a map which key is the offset of a dwarf
99/// die and which value is the corresponding artefact.
100typedef unordered_map<Dwarf_Off, type_or_decl_base_sptr> die_artefact_map_type;
101
102/// Convenience typedef for a map which key is the offset of a dwarf
103/// die, (given by dwarf_dieoffset()) and which value is the
104/// corresponding class_decl.
105typedef unordered_map<Dwarf_Off, class_decl_sptr> die_class_map_type;
106
107/// Convenience typedef for a map which key is the offset of a dwarf
108/// die, (given by dwarf_dieoffset()) and which value is the
109/// corresponding class_or_union_sptr.
110typedef unordered_map<Dwarf_Off, class_or_union_sptr> die_class_or_union_map_type;
111
112/// Convenience typedef for a map which key the offset of a dwarf die
113/// and which value is the corresponding function_decl.
114typedef unordered_map<Dwarf_Off, function_decl_sptr> die_function_decl_map_type;
115
116/// Convenience typedef for a map which key is the offset of a dwarf
117/// die and which value is the corresponding function_type.
118typedef unordered_map<Dwarf_Off, function_type_sptr> die_function_type_map_type;
119
120/// Convenience typedef for a map which key is the offset of a
121/// DW_TAG_compile_unit and the value is the corresponding @ref
122/// translation_unit_sptr.
123typedef unordered_map<Dwarf_Off, translation_unit_sptr> die_tu_map_type;
124
125/// Convenience typedef for a map which key is the offset of a DIE and
126/// the value is the corresponding qualified name of the DIE.
127typedef unordered_map<Dwarf_Off, interned_string> die_istring_map_type;
128
129/// Convenience typedef for a map which is an interned_string and
130/// which value is a vector of offsets.
131typedef unordered_map<interned_string,
135
136/// A hasher for a pair of Dwarf_Off. This is used as a hasher for
137/// the type @ref dwarf_offset_pair_set_type.
138struct dwarf_offset_pair_hash
139{
140 size_t
141 operator()(const std::pair<Dwarf_Off, Dwarf_Off>& p) const
142 {return abigail::hashing::combine_hashes(p.first, p.second);}
143};// end struct dwarf_offset_pair_hash
144
145typedef unordered_set<std::pair<Dwarf_Off,
146 Dwarf_Off>,
147 dwarf_offset_pair_hash> dwarf_offset_pair_set_type;
148
149/// An abstraction of a DIE offset that also encapsulate the source of
150/// the DIE.
151struct offset_type
152{
153 die_source source_;
154 Dwarf_Off offset_;
155
156 offset_type()
157 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
158 offset_(0)
159 {}
160
161 offset_type(die_source source, Dwarf_Off offset)
162 : source_(source),
163 offset_(offset)
164 {}
165
166 offset_type(Dwarf_Off offset)
167 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
168 offset_(offset)
169 {}
170
171 bool operator==(const offset_type& o) const
172 {return source_ == o.source_ && offset_ == o.offset_;}
173
174 operator Dwarf_Off() const
175 {return offset_;}
176}; // end struct offset_type
177
178/// A convenience typedef for a pair of offset_type.
179typedef std::pair<offset_type, offset_type> offset_pair_type;
180
181/// A hasher for an instance of offset_type.
182struct offset_hash
183{
184 size_t
185 operator()(const offset_type& p) const
186 {return abigail::hashing::combine_hashes(p.source_, p.offset_);}
187};// end struct offset_hash
188
189/// A hasher for a pair of offset_type. This is used as a hasher for
190/// the type @ref offset_pair_set_type, for instance.
191struct offset_pair_hash
192{
193 size_t
194 operator()(const std::pair<offset_type, offset_type>& p) const
195 {
196 size_t h1 = abigail::hashing::combine_hashes(p.first.source_,
197 p.first.offset_);
198 size_t h2 = abigail::hashing::combine_hashes(p.second.source_,
199 p.second.offset_);
200 return abigail::hashing::combine_hashes(h1, h2);
201 }
202};// end struct offset_pair_hash
203
204/// A convenience typedef for an unordered set of DIE offsets.
205typedef unordered_set<offset_type, offset_hash> offset_set_type;
206
207///A convenience typedef for an unordered set of pairs of offset_type.
208typedef unordered_set<std::pair<offset_type,
209 offset_type>,
210 offset_pair_hash> offset_pair_set_type;
211
212/// A convenience typedef for a vector of pairs of offset_type.
213typedef vector<std::pair<offset_type, offset_type>> offset_pair_vector_type;
214
215/// A convenience typedef for an unordered map that associates a pair
216/// of offset_type to a vector of pairs offset_type.
217typedef unordered_map<std::pair<offset_type, offset_type>,
219 offset_pair_hash> offset_pair_vect_map_type;
220
221/// A convenience typedef for an unordered_map that associates a pair
222/// of offset_type to a set of pairs of offset_type.
223typedef unordered_map<std::pair<offset_type, offset_type>,
225 offset_pair_hash> offset_pair_set_map_type;
226
227/// A convenience typedef for a vector of pairs of offset_type.
228typedef vector<std::pair<offset_type, offset_type>> offset_pair_vector_type;
229
230class reader;
231
233build_translation_unit_and_add_to_ir(reader& rdr,
234 Dwarf_Die* die,
235 char address_size);
236
237static void
238maybe_propagate_canonical_type(const reader& rdr,
239 const Dwarf_Die* l,
240 const Dwarf_Die* r);
241
242static void
243propagate_canonical_type(const reader& rdr,
244 const Dwarf_Die* l,
245 const Dwarf_Die* r);
246
247/// Convenience typedef for a shared pointer to an
248/// addr_elf_symbol_sptr_map_type.
249typedef shared_ptr<addr_elf_symbol_sptr_map_type> addr_elf_symbol_sptr_map_sptr;
250
251/// Convenience typedef for a map that associates an @ref
252/// interned_string to a @ref function_type_sptr.
253typedef unordered_map<interned_string,
256
257/// Convenience typedef for a stack containing the scopes up to the
258/// current point in the abigail Internal Representation (aka IR) tree
259/// that is being built.
260typedef stack<scope_decl*> scope_stack_type;
261
262/// Convenience typedef for a map which key is a dwarf offset. The
263/// value is also a dwarf offset.
264typedef unordered_map<Dwarf_Off, Dwarf_Off> offset_offset_map_type;
265
266/// Convenience typedef for a map which key is a string and which
267/// value is a vector of smart pointer to a class_or_union_sptr.
268typedef unordered_map<string, classes_or_unions_type> string_classes_or_unions_map;
269
270/// Convenience typedef for a map which key is a string and which
271/// value is a vector of smart pointer to a class.
272typedef unordered_map<string, classes_type> string_classes_map;
273
274/// Convenience typedef for a map which key is a string and which
275/// value is a vector of smart pointer to a enum.
276typedef unordered_map<string, enums_type> string_enums_map;
277
278/// The abstraction of the place where a partial unit has been
279/// imported. This is what the DW_TAG_imported_unit DIE expresses.
280///
281/// This type thus contains:
282/// - the offset to which the partial unit is imported
283/// - the offset of the imported partial unit.
284/// - the offset of the imported partial unit.
285struct imported_unit_point
286{
287 Dwarf_Off offset_of_import;
288 // The boolean below is true iff the imported unit comes from the
289 // alternate debug info file.
290 die_source imported_unit_die_source;
291 Dwarf_Off imported_unit_die_off;
292 Dwarf_Off imported_unit_cu_off;
293 Dwarf_Off imported_unit_child_off;
294
295 /// Default constructor for @ref the type imported_unit_point.
296 imported_unit_point()
297 : offset_of_import(),
298 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
299 imported_unit_die_off(),
300 imported_unit_cu_off(),
301 imported_unit_child_off()
302 {}
303
304 /// Constructor of @ref the type imported_unit_point.
305 ///
306 /// @param import_off the offset of the point at which the unit has
307 /// been imported.
308 imported_unit_point(Dwarf_Off import_off)
309 : offset_of_import(import_off),
310 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
311 imported_unit_die_off(),
312 imported_unit_cu_off(),
313 imported_unit_child_off()
314 {}
315
316 /// Constructor of @ref the type imported_unit_point.
317 ///
318 /// @param import_off the offset of the point at which the unit has
319 /// been imported.
320 ///
321 /// @param from where the imported DIE comes from.
322 ///
323 /// @param imported_die the die of the unit that has been imported.
324 imported_unit_point(Dwarf_Off import_off,
325 const Dwarf_Die& imported_die,
326 die_source from)
327 : offset_of_import(import_off),
328 imported_unit_die_source(from),
329 imported_unit_die_off(dwarf_dieoffset
330 (const_cast<Dwarf_Die*>(&imported_die))),
331 imported_unit_cu_off(),
332 imported_unit_child_off()
333 {
334 Dwarf_Die imported_unit_child;
335
336 ABG_ASSERT(dwarf_child(const_cast<Dwarf_Die*>(&imported_die),
337 &imported_unit_child) == 0);
338
339 imported_unit_child_off =
340 dwarf_dieoffset(const_cast<Dwarf_Die*>(&imported_unit_child));
341
342 Dwarf_Die cu_die_memory;
343 Dwarf_Die *cu_die;
344
345 cu_die = dwarf_diecu(const_cast<Dwarf_Die*>(&imported_unit_child),
346 &cu_die_memory, 0, 0);
347 imported_unit_cu_off = dwarf_dieoffset(cu_die);
348 }
349}; // struct imported_unit_point
350
351/// Convenience typedef for a vector of @ref imported_unit_point.
352typedef vector<imported_unit_point> imported_unit_points_type;
353
354/// Convenience typedef for a vector of @ref imported_unit_point.
355typedef unordered_map<Dwarf_Off, imported_unit_points_type>
357
358/// "Less than" operator for instances of @ref imported_unit_point
359/// type.
360///
361/// @param the left hand side operand of the "Less than" operator.
362///
363/// @param the right hand side operand of the "Less than" operator.
364///
365/// @return true iff @p l is less than @p r.
366static bool
367operator<(const imported_unit_point& l, const imported_unit_point& r)
368{return l.offset_of_import < r.offset_of_import;}
369
370static bool
371get_parent_die(const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
375
376static bool
377get_scope_die(const reader& rdr,
378 const Dwarf_Die* die,
379 size_t where_offset,
380 Dwarf_Die& scope_die);
381
382static bool
383die_is_anonymous(const Dwarf_Die* die);
384
385static bool
386die_is_anonymous_data_member(const Dwarf_Die* die);
387
388static bool
389die_is_type(const Dwarf_Die* die);
390
391static bool
392die_is_decl(const Dwarf_Die* die);
393
394static bool
395die_is_declaration_only(Dwarf_Die* die);
396
397static bool
398die_is_variable_decl(const Dwarf_Die *die);
399
400static bool
401die_is_function_decl(const Dwarf_Die *die);
402
403static bool
404die_has_size_attribute(const Dwarf_Die *die);
405
406static bool
407die_has_no_child(const Dwarf_Die *die);
408
409static bool
410die_is_namespace(const Dwarf_Die* die);
411
412static bool
413die_is_unspecified(Dwarf_Die* die);
414
415static bool
416die_is_void_type(Dwarf_Die* die);
417
418static bool
419die_is_pointer_type(const Dwarf_Die* die);
420
421static bool
422pointer_or_qual_die_of_anonymous_class_type(const Dwarf_Die* die);
423
424static bool
425die_is_reference_type(const Dwarf_Die* die);
426
427static bool
428die_is_pointer_array_or_reference_type(const Dwarf_Die* die);
429
430static bool
431die_is_pointer_or_reference_type(const Dwarf_Die* die);
432
433static bool
434die_is_pointer_reference_or_typedef_type(const Dwarf_Die* die);
435
436static bool
437die_is_class_type(const Dwarf_Die* die);
438
439static bool
440die_is_qualified_type(const Dwarf_Die* die);
441
442static bool
443die_is_function_type(const Dwarf_Die *die);
444
445static bool
446die_has_object_pointer(const Dwarf_Die* die,
447 Dwarf_Die& object_pointer);
448
449static bool
450die_has_children(const Dwarf_Die* die);
451
452static bool
453die_this_pointer_from_object_pointer(Dwarf_Die* die,
454 Dwarf_Die& this_pointer);
455
456static bool
457die_this_pointer_is_const(Dwarf_Die* die);
458
459static bool
460die_object_pointer_is_for_const_method(Dwarf_Die* die);
461
462static bool
463is_type_die_to_be_canonicalized(const Dwarf_Die *die);
464
465static bool
466die_is_at_class_scope(const reader& rdr,
467 const Dwarf_Die* die,
468 size_t where_offset,
469 Dwarf_Die& class_scope_die);
470static bool
471eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
472 size_t expr_len,
473 int64_t& value,
474 bool& is_tls_address);
475
477dwarf_language_to_tu_language(size_t l);
478
479static bool
480die_unsigned_constant_attribute(const Dwarf_Die* die,
481 unsigned attr_name,
482 uint64_t& cst);
483
484static bool
485die_signed_constant_attribute(const Dwarf_Die*die,
486 unsigned attr_name,
487 int64_t& cst);
488
489static bool
490die_constant_attribute(const Dwarf_Die *die,
491 unsigned attr_name,
492 bool is_signed,
493 array_type_def::subrange_type::bound_value &value);
494
495static bool
496die_member_offset(const reader& rdr,
497 const Dwarf_Die* die,
498 int64_t& offset);
499
500static bool
501form_is_DW_FORM_strx(unsigned form);
502
503static bool
504form_is_DW_FORM_line_strp(unsigned form);
505
506static bool
507die_address_attribute(Dwarf_Die* die, unsigned attr_name, Dwarf_Addr& result);
508
509static string
510die_name(const Dwarf_Die* die);
511
512static location
513die_location(const reader& rdr, const Dwarf_Die* die);
514
515static bool
516die_location_address(Dwarf_Die* die,
517 Dwarf_Addr& address,
518 bool& is_tls_address);
519
520static bool
521die_die_attribute(const Dwarf_Die* die,
522 unsigned attr_name,
523 Dwarf_Die& result,
524 bool recursively = true);
525
526static bool
527subrange_die_indirect_bound_value(const Dwarf_Die *die,
528 unsigned attr_name,
529 array_type_def::subrange_type::bound_value& v,
530 bool& is_signed);
531
532static bool
533subrange_die_indirectly_references_subrange_die(const Dwarf_Die *die,
534 unsigned attr_name,
535 Dwarf_Die& referenced_subrange);
536static string
537get_internal_anonymous_die_prefix_name(const Dwarf_Die *die);
538
539static string
540build_internal_anonymous_die_name(const string &base_name,
541 size_t anonymous_type_index);
542
543static string
544get_internal_anonymous_die_name(Dwarf_Die *die,
545 size_t anonymous_type_index);
546
547static string
548die_qualified_type_name(const reader& rdr,
549 const Dwarf_Die* die,
550 size_t where);
551
552static string
553die_qualified_decl_name(const reader& rdr,
554 const Dwarf_Die* die,
555 size_t where);
556
557static string
558die_qualified_name(const reader& rdr,
559 const Dwarf_Die* die,
560 size_t where);
561
562static bool
563die_qualified_type_name_empty(const reader& rdr,
564 const Dwarf_Die* die, size_t where,
565 string &qualified_name);
566
567static void
568die_return_and_parm_names_from_fn_type_die(const reader& rdr,
569 const Dwarf_Die* die,
570 size_t where_offset,
571 bool pretty_print,
572 string &return_type_name,
573 string &class_name,
574 vector<string>& parm_names,
575 bool& is_const,
576 bool& is_static);
577
578static string
579die_function_signature(const reader& rdr,
580 const Dwarf_Die *die,
581 size_t where_offset);
582
583static bool
584die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
585
586static bool
587die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
588
589static bool
590die_function_type_is_method_type(const reader& rdr,
591 const Dwarf_Die *die,
592 size_t where_offset,
593 Dwarf_Die& object_pointer_die,
594 Dwarf_Die& class_die,
595 bool& is_static);
596
597static string
598die_pretty_print_type(reader& rdr,
599 const Dwarf_Die* die,
600 size_t where_offset);
601
602static string
603die_pretty_print_decl(reader& rdr,
604 const Dwarf_Die* die,
605 size_t where_offset);
606
607static string
608die_pretty_print(reader& rdr,
609 const Dwarf_Die* die,
610 size_t where_offset);
611
612static void
613maybe_canonicalize_type(const type_base_sptr& t,
614 reader& rdr);
615
616static uint64_t
617get_default_array_lower_bound(translation_unit::language l);
618
619static bool
620find_lower_bound_in_imported_unit_points(const imported_unit_points_type&,
621 Dwarf_Off,
622 imported_unit_points_type::const_iterator&);
623
625build_subrange_type(reader& rdr,
626 const Dwarf_Die* die,
627 size_t where_offset,
628 bool associate_type_to_die = true);
629
630static void
631build_subranges_from_array_type_die(reader& rdr,
632 const Dwarf_Die* die,
634 size_t where_offset,
635 bool associate_type_to_die = true);
636
638compare_dies(const reader& rdr,
639 const Dwarf_Die *l, const Dwarf_Die *r,
640 bool update_canonical_dies_on_the_fly);
641
642static bool
643compare_dies_during_canonicalization(reader& rdr,
644 const Dwarf_Die *l, const Dwarf_Die *r,
645 bool update_canonical_dies_on_the_fly);
646
647static bool
648get_member_child_die(const Dwarf_Die *die, Dwarf_Die *child);
649
650/// Compare a symbol name against another name, possibly demangling
651/// the symbol_name before performing the comparison.
652///
653/// @param symbol_name the symbol_name to take in account.
654///
655/// @param name the second name to take in account.
656///
657/// @param demangle if true, demangle @p symbol_name and compare the
658/// result of the demangling with @p name.
659///
660/// @return true iff symbol_name equals name.
661static bool
662compare_symbol_name(const string& symbol_name,
663 const string& name,
664 bool demangle)
665{
666 if (demangle)
667 {
668 string m = demangle_cplus_mangled_name(symbol_name);
669 return m == name;
670 }
671 return symbol_name == name;
672}
673
674/// Lookup a symbol using the SysV ELF hash table.
675///
676/// Note that this function hasn't been tested. So it hasn't been
677/// debugged yet. IOW, it is not known to work. Or rather, it's
678/// almost like it's surely doesn't work ;-)
679///
680/// Use it at your own risks. :-)
681///
682///@parm env the environment we are operating from.
683///
684/// @param elf_handle the elf_handle to use.
685///
686/// @param sym_name the symbol name to look for.
687///
688/// @param ht_index the index (in the section headers table) of the
689/// hash table section to use.
690///
691/// @param sym_tab_index the index (in the section headers table) of
692/// the symbol table to use.
693///
694/// @param demangle if true, demangle @p sym_name before comparing it
695/// to names from the symbol table.
696///
697/// @param syms_found a vector of symbols found with the name @p
698/// sym_name. table.
699static bool
700lookup_symbol_from_sysv_hash_tab(const environment& env,
701 Elf* elf_handle,
702 const string& sym_name,
703 size_t ht_index,
704 size_t sym_tab_index,
705 bool demangle,
706 vector<elf_symbol_sptr>& syms_found)
707{
708 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
709 ABG_ASSERT(sym_tab_section);
710
711 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
712 ABG_ASSERT(sym_tab_data);
713
714 GElf_Shdr sheader_mem;
715 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
716 &sheader_mem);
717 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
718 ABG_ASSERT(hash_section);
719
720 // Poke at the different parts of the hash table and get them ready
721 // to be used.
722 unsigned long hash = elf_hash(sym_name.c_str());
723 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
724 Elf32_Word* ht_data = reinterpret_cast<Elf32_Word*>(ht_section_data->d_buf);
725 size_t nb_buckets = ht_data[0];
726 size_t nb_chains = ht_data[1];
727
728 if (nb_buckets == 0)
729 // An empty hash table. Not sure if that is possible, but it
730 // would mean an empty table of exported symbols.
731 return false;
732
733 //size_t nb_chains = ht_data[1];
734 Elf32_Word* ht_buckets = &ht_data[2];
735 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
736
737 // Now do the real work.
738 size_t bucket = hash % nb_buckets;
739 size_t symbol_index = ht_buckets[bucket];
740
741 GElf_Sym symbol;
742 const char* sym_name_str;
743 size_t sym_size;
744 elf_symbol::type sym_type;
745 elf_symbol::binding sym_binding;
746 elf_symbol::visibility sym_visibility;
747 bool found = false;
748
749 do
750 {
751 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
752 sym_name_str = elf_strptr(elf_handle,
753 sym_tab_section_header->sh_link,
754 symbol.st_name);
755 if (sym_name_str
756 && compare_symbol_name(sym_name_str, sym_name, demangle))
757 {
758 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
759 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
760 sym_visibility =
761 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
762 sym_size = symbol.st_size;
763 elf_symbol::version ver;
764 if (get_version_for_symbol(elf_handle, symbol_index,
765 /*get_def_version=*/true, ver))
766 ABG_ASSERT(!ver.str().empty());
767 elf_symbol_sptr symbol_found =
769 symbol_index,
770 sym_size,
771 sym_name_str,
772 sym_type,
773 sym_binding,
774 symbol.st_shndx != SHN_UNDEF,
775 symbol.st_shndx == SHN_COMMON,
776 ver, sym_visibility);
777 syms_found.push_back(symbol_found);
778 found = true;
779 }
780 symbol_index = ht_chains[symbol_index];
781 } while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
782
783 return found;
784}
785
786/// Get the size of the elf class, in bytes.
787///
788/// @param elf_handle the elf handle to use.
789///
790/// @return the size computed.
791static char
792get_elf_class_size_in_bytes(Elf* elf_handle)
793{
794 char result = 0;
795 GElf_Ehdr hdr;
796
797 ABG_ASSERT(gelf_getehdr(elf_handle, &hdr));
798 int c = hdr.e_ident[EI_CLASS];
799
800 switch (c)
801 {
802 case ELFCLASS32:
803 result = 4;
804 break;
805 case ELFCLASS64:
806 result = 8;
807 break;
808 default:
810 }
811
812 return result;
813}
814
815/// Get a given word of a bloom filter, referred to by the index of
816/// the word.
817///
818/// The bloom word size depends on the current elf class (32 bits for
819/// an ELFCLASS32 or 64 bits for an ELFCLASS64 one) and this function
820/// abstracts that nicely.
821///
822/// @param elf_handle the elf handle to use.
823///
824/// @param bloom_filter the bloom filter to consider.
825///
826/// @param index the index of the bloom filter to return.
827///
828/// @return a 64 bits work containing the bloom word found at index @p
829/// index. Note that if we are looking at an ELFCLASS32 binary, the 4
830/// most significant bytes of the result are going to be zero.
831static Elf64_Xword
832bloom_word_at(Elf* elf_handle,
833 Elf32_Word* bloom_filter,
834 size_t index)
835{
836 Elf64_Xword result = 0;
837 GElf_Ehdr h;
838 ABG_ASSERT(gelf_getehdr(elf_handle, &h));
839 int c;
840 c = h.e_ident[EI_CLASS];
841
842 switch(c)
843 {
844 case ELFCLASS32:
845 result = bloom_filter[index];
846 break ;
847 case ELFCLASS64:
848 {
849 Elf64_Xword* f= reinterpret_cast<Elf64_Xword*>(bloom_filter);
850 result = f[index];
851 }
852 break;
853 default:
854 abort();
855 }
856
857 return result;
858}
859
860/// The abstraction of the gnu elf hash table.
861///
862/// The members of this struct are explained at
863/// - https://sourceware.org/ml/binutils/2006-10/msg00377.html
864/// - https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections.
865struct gnu_ht
866{
867 size_t nb_buckets;
868 Elf32_Word* buckets;
869 Elf32_Word* chain;
870 size_t first_sym_index;
871 size_t bf_nwords;
872 size_t bf_size;
873 Elf32_Word* bloom_filter;
874 size_t shift;
875 size_t sym_count;
876 Elf_Scn* sym_tab_section;
877 GElf_Shdr sym_tab_section_header;
878
879 gnu_ht()
880 : nb_buckets(0),
881 buckets(0),
882 chain(0),
883 first_sym_index(0),
884 bf_nwords(0),
885 bf_size(0),
886 bloom_filter(0),
887 shift(0),
888 sym_count(0),
889 sym_tab_section(0)
890 {}
891}; // end struct gnu_ht
892
893/// Setup the members of the gnu hash table.
894///
895/// @param elf_handle a handle on the elf file to use.
896///
897/// @param ht_index the index (into the elf section headers table) of
898/// the hash table section to use.
899///
900/// @param sym_tab_index the index (into the elf section headers
901/// table) of the symbol table the gnu hash table is about.
902///
903/// @param ht the resulting hash table.
904///
905/// @return true iff the hash table @ ht could be setup.
906static bool
907setup_gnu_ht(Elf* elf_handle,
908 size_t ht_index,
909 size_t sym_tab_index,
910 gnu_ht& ht)
911{
912 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
913 ABG_ASSERT(ht.sym_tab_section);
914 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
915 ht.sym_count =
916 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
917 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
918 ABG_ASSERT(hash_section);
919
920 // Poke at the different parts of the hash table and get them ready
921 // to be used.
922 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
923 Elf32_Word* ht_data = reinterpret_cast<Elf32_Word*>(ht_section_data->d_buf);
924
925 ht.nb_buckets = ht_data[0];
926 if (ht.nb_buckets == 0)
927 // An empty hash table. Not sure if that is possible, but it
928 // would mean an empty table of exported symbols.
929 return false;
930 ht.first_sym_index = ht_data[1];
931 // The number of words used by the bloom filter. A size of a word
932 // is ELFCLASS.
933 ht.bf_nwords = ht_data[2];
934 // The shift used by the bloom filter code.
935 ht.shift = ht_data[3];
936 // The data of the bloom filter proper.
937 ht.bloom_filter = &ht_data[4];
938 // The size of the bloom filter in 4 bytes word. This is going to
939 // be used to index the 'bloom_filter' above, which is of type
940 // Elf32_Word*; thus we need that bf_size be expressed in 4 bytes
941 // words.
942 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
943 // The buckets of the hash table.
944 ht.buckets = ht.bloom_filter + ht.bf_size;
945 // The chain of the hash table.
946 ht.chain = ht.buckets + ht.nb_buckets;
947
948 return true;
949}
950
951/// Look into the symbol tables of the underlying elf file and find
952/// the symbol we are being asked.
953///
954/// This function uses the GNU hash table for the symbol lookup.
955///
956/// The reference of for the implementation of this function can be
957/// found at:
958/// - https://sourceware.org/ml/binutils/2006-10/msg00377.html
959/// - https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections.
960///
961/// @param elf_handle the elf handle to use.
962///
963/// @param sym_name the name of the symbol to look for.
964///
965/// @param ht_index the index of the hash table header to use.
966///
967/// @param sym_tab_index the index of the symbol table header to use
968/// with this hash table.
969///
970/// @param demangle if true, demangle @p sym_name.
971///
972/// @param syms_found the vector of symbols found with the name @p
973/// sym_name.
974///
975/// @return true if a symbol was actually found.
976static bool
977lookup_symbol_from_gnu_hash_tab(const environment& env,
978 Elf* elf_handle,
979 const string& sym_name,
980 size_t ht_index,
981 size_t sym_tab_index,
982 bool demangle,
983 vector<elf_symbol_sptr>& syms_found)
984{
985 gnu_ht ht;
986 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
987 return false;
988
989 // Now do the real work.
990
991 // Compute bloom hashes (GNU hash and second bloom specific hashes).
992 size_t h1 = elf_gnu_hash(sym_name.c_str());
993 size_t h2 = h1 >> ht.shift;
994 // The size of one of the words used in the bloom
995 // filter, in bits.
996 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
997 int n = (h1 / c) % ht.bf_nwords;
998 // The bitmask of the bloom filter has a size of either 32-bits on
999 // ELFCLASS32 binaries or 64-bits on ELFCLASS64 binaries. So we
1000 // need a 64-bits type to hold the bitmap, hence the Elf64_Xword
1001 // type used here. When dealing with 32bits binaries, the upper
1002 // bits of the bitmask will be zero anyway.
1003 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1004
1005 // Test if the symbol is *NOT* present in this ELF file.
1006 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1007 return false;
1008
1009 size_t i = ht.buckets[h1 % ht.nb_buckets];
1010 if (i == STN_UNDEF)
1011 return false;
1012
1013 Elf32_Word stop_word, *stop_wordp;
1014 elf_symbol::version ver;
1015 GElf_Sym symbol;
1016 const char* sym_name_str;
1017 bool found = false;
1018
1019 elf_symbol::type sym_type;
1020 elf_symbol::binding sym_binding;
1021 elf_symbol::visibility sym_visibility;
1022
1023 // Let's walk the hash table and record the versions of all the
1024 // symbols which name equal sym_name.
1025 for (i = ht.buckets[h1 % ht.nb_buckets],
1026 stop_wordp = &ht.chain[i - ht.first_sym_index];
1027 i != STN_UNDEF
1028 && (stop_wordp
1029 < ht.chain + (ht.sym_count - ht.first_sym_index));
1030 ++i, ++stop_wordp)
1031 {
1032 stop_word = *stop_wordp;
1033 if ((stop_word & ~ 1)!= (h1 & ~1))
1034 // A given bucket can reference several hashes. Here we
1035 // stumbled across a hash value different from the one we are
1036 // looking for. Let's keep walking.
1037 continue;
1038
1039 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1040 i, &symbol));
1041 sym_name_str = elf_strptr(elf_handle,
1042 ht.sym_tab_section_header.sh_link,
1043 symbol.st_name);
1044 if (sym_name_str
1045 && compare_symbol_name(sym_name_str, sym_name, demangle))
1046 {
1047 // So we found a symbol (in the symbol table) that equals
1048 // sym_name. Now lets try to get its version and record it.
1049 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
1050 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
1051 sym_visibility =
1052 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
1053
1054 if (get_version_for_symbol(elf_handle, i,
1055 /*get_def_version=*/true,
1056 ver))
1057 ABG_ASSERT(!ver.str().empty());
1058
1059 elf_symbol_sptr symbol_found =
1060 elf_symbol::create(env, i,
1061 symbol.st_size,
1062 sym_name_str,
1063 sym_type, sym_binding,
1064 symbol.st_shndx != SHN_UNDEF,
1065 symbol.st_shndx == SHN_COMMON,
1066 ver, sym_visibility);
1067 syms_found.push_back(symbol_found);
1068 found = true;
1069 }
1070
1071 if (stop_word & 1)
1072 // The last bit of the stop_word is 1. That means we need to
1073 // stop here. We reached the end of the chain of values
1074 // referenced by the hask bucket.
1075 break;
1076 }
1077 return found;
1078}
1079
1080/// Look into the symbol tables of the underlying elf file and find
1081/// the symbol we are being asked.
1082///
1083/// This function uses the elf hash table (be it the GNU hash table or
1084/// the sysv hash table) for the symbol lookup.
1085///
1086/// @param env the environment we are operating from.
1087///
1088/// @param elf_handle the elf handle to use.
1089///
1090/// @param ht_kind the kind of hash table to use. This is returned by
1091/// the function function find_hash_table_section_index.
1092///
1093/// @param ht_index the index (in the section headers table) of the
1094/// hash table section to use.
1095///
1096/// @param sym_tab_index the index (in section headers table) of the
1097/// symbol table index to use with this hash table.
1098///
1099/// @param symbol_name the name of the symbol to look for.
1100///
1101/// @param demangle if true, demangle @p sym_name.
1102///
1103/// @param syms_found the symbols that were actually found with the
1104/// name @p symbol_name.
1105///
1106/// @return true iff the function found the symbol from the elf hash
1107/// table.
1108static bool
1109lookup_symbol_from_elf_hash_tab(const environment& env,
1110 Elf* elf_handle,
1111 hash_table_kind ht_kind,
1112 size_t ht_index,
1113 size_t symtab_index,
1114 const string& symbol_name,
1115 bool demangle,
1116 vector<elf_symbol_sptr>& syms_found)
1117{
1118 if (elf_handle == 0 || symbol_name.empty())
1119 return false;
1120
1121 if (ht_kind == NO_HASH_TABLE_KIND)
1122 return false;
1123
1124 if (ht_kind == SYSV_HASH_TABLE_KIND)
1125 return lookup_symbol_from_sysv_hash_tab(env,
1126 elf_handle, symbol_name,
1127 ht_index,
1128 symtab_index,
1129 demangle,
1130 syms_found);
1131 else if (ht_kind == GNU_HASH_TABLE_KIND)
1132 return lookup_symbol_from_gnu_hash_tab(env,
1133 elf_handle, symbol_name,
1134 ht_index,
1135 symtab_index,
1136 demangle,
1137 syms_found);
1138 return false;
1139}
1140
1141/// Lookup a symbol from the symbol table directly.
1142///
1143///
1144/// @param env the environment we are operating from.
1145///
1146/// @param elf_handle the elf handle to use.
1147///
1148/// @param sym_name the name of the symbol to look up.
1149///
1150/// @param sym_tab_index the index (in the section headers table) of
1151/// the symbol table section.
1152///
1153/// @param demangle if true, demangle the names found in the symbol
1154/// table before comparing them with @p sym_name.
1155///
1156/// @param sym_name_found the actual name of the symbol found.
1157///
1158/// @param sym_type the type of the symbol found.
1159///
1160/// @param sym_binding the binding of the symbol found.
1161///
1162/// @param sym_versions the versions of the symbol found.
1163///
1164/// @return true iff the symbol was found.
1165static bool
1166lookup_symbol_from_symtab(const environment& env,
1167 Elf* elf_handle,
1168 const string& sym_name,
1169 size_t sym_tab_index,
1170 bool demangle,
1171 vector<elf_symbol_sptr>& syms_found)
1172{
1173 // TODO: read all of the symbol table, store it in memory in a data
1174 // structure that associates each symbol with its versions and in
1175 // which lookups of a given symbol is fast.
1176 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1177 ABG_ASSERT(sym_tab_section);
1178
1179 GElf_Shdr header_mem;
1180 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1181 &header_mem);
1182
1183 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1184 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1185 GElf_Sym* sym;
1186 char* name_str = 0;
1187 elf_symbol::version ver;
1188 bool found = false;
1189
1190 for (size_t i = 0; i < symcount; ++i)
1191 {
1192 GElf_Sym sym_mem;
1193 sym = gelf_getsym(symtab, i, &sym_mem);
1194 name_str = elf_strptr(elf_handle,
1195 sym_tab_header->sh_link,
1196 sym->st_name);
1197
1198 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1199 {
1200 elf_symbol::type sym_type =
1201 stt_to_elf_symbol_type(GELF_ST_TYPE(sym->st_info));
1202 elf_symbol::binding sym_binding =
1203 stb_to_elf_symbol_binding(GELF_ST_BIND(sym->st_info));
1204 elf_symbol::visibility sym_visibility =
1205 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(sym->st_other));
1206 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1207 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1208
1209 if (get_version_for_symbol(elf_handle, i,
1210 /*get_def_version=*/sym_is_defined,
1211 ver))
1212 ABG_ASSERT(!ver.str().empty());
1213 elf_symbol_sptr symbol_found =
1214 elf_symbol::create(env, i, sym->st_size,
1215 name_str, sym_type,
1216 sym_binding, sym_is_defined,
1217 sym_is_common, ver, sym_visibility);
1218 syms_found.push_back(symbol_found);
1219 found = true;
1220 }
1221 }
1222
1223 if (found)
1224 return true;
1225
1226 return false;
1227}
1228
1229/// Look into the symbol tables of the underlying elf file and see
1230/// if we find a given symbol.
1231///
1232/// @param env the environment we are operating from.
1233///
1234/// @param symbol_name the name of the symbol to look for.
1235///
1236/// @param demangle if true, try to demangle the symbol name found in
1237/// the symbol table before comparing it to @p symbol_name.
1238///
1239/// @param syms_found the list of symbols found, with the name @p
1240/// symbol_name.
1241///
1242/// @param sym_type this is set to the type of the symbol found. This
1243/// shall b a standard elf.h value for symbol types, that is SHT_OBJECT,
1244/// STT_FUNC, STT_IFUNC, etc ...
1245///
1246/// Note that this parameter is set iff the function returns true.
1247///
1248/// @param sym_binding this is set to the binding of the symbol found.
1249/// This is a standard elf.h value of the symbol binding kind, that
1250/// is, STB_LOCAL, STB_GLOBAL, or STB_WEAK.
1251///
1252/// @param symbol_versions the versions of the symbol @p symbol_name,
1253/// if it was found.
1254///
1255/// @return true iff a symbol with the name @p symbol_name was found.
1256static bool
1257lookup_symbol_from_elf(const environment& env,
1258 Elf* elf_handle,
1259 const string& symbol_name,
1260 bool demangle,
1261 vector<elf_symbol_sptr>& syms_found)
1262{
1263 size_t hash_table_index = 0, symbol_table_index = 0;
1264 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1265
1266 if (!demangle)
1267 ht_kind = find_hash_table_section_index(elf_handle,
1268 hash_table_index,
1269 symbol_table_index);
1270
1271 if (ht_kind == NO_HASH_TABLE_KIND)
1272 {
1273 if (!find_symbol_table_section_index(elf_handle, symbol_table_index))
1274 return false;
1275
1276 return lookup_symbol_from_symtab(env,
1277 elf_handle,
1278 symbol_name,
1279 symbol_table_index,
1280 demangle,
1281 syms_found);
1282 }
1283
1284 return lookup_symbol_from_elf_hash_tab(env,
1285 elf_handle,
1286 ht_kind,
1287 hash_table_index,
1288 symbol_table_index,
1289 symbol_name,
1290 demangle,
1291 syms_found);
1292}
1293
1294/// Look into the symbol tables of the underlying elf file and see if
1295/// we find a given public (global or weak) symbol of function type.
1296///
1297/// @param env the environment we are operating from.
1298///
1299/// @param elf_handle the elf handle to use for the query.
1300///
1301/// @param symbol_name the function symbol to look for.
1302///
1303/// @param func_syms the vector of public functions symbols found, if
1304/// any.
1305///
1306/// @return true iff the symbol was found.
1307static bool
1308lookup_public_function_symbol_from_elf(environment& env,
1309 Elf* elf_handle,
1310 const string& symbol_name,
1311 vector<elf_symbol_sptr>& func_syms)
1312{
1313 vector<elf_symbol_sptr> syms_found;
1314 bool found = false;
1315
1316 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1317 /*demangle=*/false, syms_found))
1318 {
1319 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1320 i != syms_found.end();
1321 ++i)
1322 {
1323 elf_symbol::type type = (*i)->get_type();
1324 elf_symbol::binding binding = (*i)->get_binding();
1325
1326 if ((type == elf_symbol::FUNC_TYPE
1327 || type == elf_symbol::GNU_IFUNC_TYPE
1328 || type == elf_symbol::COMMON_TYPE)
1329 && (binding == elf_symbol::GLOBAL_BINDING
1330 || binding == elf_symbol::WEAK_BINDING))
1331 {
1332 func_syms.push_back(*i);
1333 found = true;
1334 }
1335 }
1336 }
1337
1338 return found;
1339}
1340
1341// ---------------------------------------
1342// <location expression evaluation types>
1343// ---------------------------------------
1344
1345/// An abstraction of a value representing the result of the
1346/// evaluation of a dwarf expression. This is abstraction represents
1347/// a partial view on the possible values because we are only
1348/// interested in extracting the latest and longuest constant
1349/// sub-expression of a given dwarf expression.
1350class expr_result
1351{
1352 bool is_const_;
1353 int64_t const_value_;
1354
1355public:
1356 expr_result()
1357 : is_const_(true),
1358 const_value_(0)
1359 {}
1360
1361 expr_result(bool is_const)
1362 : is_const_(is_const),
1363 const_value_(0)
1364 {}
1365
1366 explicit expr_result(int64_t v)
1367 :is_const_(true),
1368 const_value_(v)
1369 {}
1370
1371 /// @return true if the value is a constant. Otherwise, return
1372 /// false, meaning the value represents a quantity for which we need
1373 /// inferior (a running program) state to determine the value.
1374 bool
1375 is_const() const
1376 {return is_const_;}
1377
1378
1379 /// @param f a flag saying if the value is set to a constant or not.
1380 void
1381 is_const(bool f)
1382 {is_const_ = f;}
1383
1384 /// Get the current constant value iff this represents a
1385 /// constant.
1386 ///
1387 /// @param value the out parameter. Is set to the constant value of
1388 /// the @ref expr_result. This is set iff the function return true.
1389 ///
1390 ///@return true if this has a constant value, false otherwise.
1391 bool
1392 const_value(int64_t& value)
1393 {
1394 if (is_const())
1395 {
1396 value = const_value_;
1397 return true;
1398 }
1399 return false;
1400 }
1401
1402 /// Getter of the constant value of the current @ref expr_result.
1403 ///
1404 /// Note that the current @ref expr_result must be constant,
1405 /// otherwise the current process is aborted.
1406 ///
1407 /// @return the constant value of the current @ref expr_result.
1408 int64_t
1409 const_value() const
1410 {
1411 ABG_ASSERT(is_const());
1412 return const_value_;
1413 }
1414
1415 operator int64_t() const
1416 {return const_value();}
1417
1418 expr_result&
1419 operator=(const int64_t v)
1420 {
1421 const_value_ = v;
1422 return *this;
1423 }
1424
1425 bool
1426 operator==(const expr_result& o) const
1427 {return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1428
1429 bool
1430 operator>=(const expr_result& o) const
1431 {return const_value_ >= o.const_value_;}
1432
1433 bool
1434 operator<=(const expr_result& o) const
1435 {return const_value_ <= o.const_value_;}
1436
1437 bool
1438 operator>(const expr_result& o) const
1439 {return const_value_ > o.const_value_;}
1440
1441 bool
1442 operator<(const expr_result& o) const
1443 {return const_value_ < o.const_value_;}
1444
1445 expr_result
1446 operator+(const expr_result& v) const
1447 {
1448 expr_result r(*this);
1449 r.const_value_ += v.const_value_;
1450 r.is_const_ = r.is_const_ && v.is_const_;
1451 return r;
1452 }
1453
1454 expr_result&
1455 operator+=(int64_t v)
1456 {
1457 const_value_ += v;
1458 return *this;
1459 }
1460
1461 expr_result
1462 operator-(const expr_result& v) const
1463 {
1464 expr_result r(*this);
1465 r.const_value_ -= v.const_value_;
1466 r.is_const_ = r.is_const_ && v.is_const_;
1467 return r;
1468 }
1469
1470 expr_result
1471 operator%(const expr_result& v) const
1472 {
1473 expr_result r(*this);
1474 r.const_value_ %= v.const_value_;
1475 r.is_const_ = r.is_const_ && v.is_const();
1476 return r;
1477 }
1478
1479 expr_result
1480 operator*(const expr_result& v) const
1481 {
1482 expr_result r(*this);
1483 r.const_value_ *= v.const_value_;
1484 r.is_const_ = r.is_const_ && v.is_const();
1485 return r;
1486 }
1487
1488 expr_result
1489 operator|(const expr_result& v) const
1490 {
1491 expr_result r(*this);
1492 r.const_value_ |= v.const_value_;
1493 r.is_const_ = r.is_const_ && v.is_const_;
1494 return r;
1495 }
1496
1497 expr_result
1498 operator^(const expr_result& v) const
1499 {
1500 expr_result r(*this);
1501 r.const_value_ ^= v.const_value_;
1502 r.is_const_ = r.is_const_ && v.is_const_;
1503 return r;
1504 }
1505
1506 expr_result
1507 operator>>(const expr_result& v) const
1508 {
1509 expr_result r(*this);
1510 r.const_value_ = r.const_value_ >> v.const_value_;
1511 r.is_const_ = r.is_const_ && v.is_const_;
1512 return r;
1513 }
1514
1515 expr_result
1516 operator<<(const expr_result& v) const
1517 {
1518 expr_result r(*this);
1519 r.const_value_ = r.const_value_ << v.const_value_;
1520 r.is_const_ = r.is_const_ && v.is_const_;
1521 return r;
1522 }
1523
1524 expr_result
1525 operator~() const
1526 {
1527 expr_result r(*this);
1528 r.const_value_ = ~r.const_value_;
1529 return r;
1530 }
1531
1532 expr_result
1533 neg() const
1534 {
1535 expr_result r(*this);
1536 r.const_value_ = -r.const_value_;
1537 return r;
1538 }
1539
1540 expr_result
1541 abs() const
1542 {
1543 expr_result r = *this;
1544 r.const_value_ = std::abs(static_cast<long double>(r.const_value()));
1545 return r;
1546 }
1547
1548 expr_result
1549 operator&(const expr_result& o)
1550 {
1551 expr_result r(*this);
1552 r.const_value_ &= o.const_value_;
1553 r.is_const_ = r.is_const_ && o.is_const_;
1554 return r;
1555 }
1556
1557 expr_result
1558 operator/(const expr_result& o)
1559 {
1560 expr_result r(*this);
1561 r.is_const_ = r.is_const_ && o.is_const_;
1562 return r.const_value() / o.const_value();
1563 }
1564};// class end expr_result;
1565
1566/// A class that implements a stack of @ref expr_result, to be used in
1567/// the engine evaluating DWARF expressions.
1568class expr_result_stack_type
1569{
1570 vector<expr_result> elems_;
1571
1572public:
1573
1574 expr_result_stack_type()
1575 {elems_.reserve(4);}
1576
1577 expr_result&
1578 operator[](unsigned i)
1579 {
1580 unsigned s = elems_.size();
1581 ABG_ASSERT(s > i);
1582 return elems_[s - 1 -i];
1583 }
1584
1585 const expr_result&
1586 operator[](unsigned i) const
1587 {return const_cast<expr_result_stack_type*>(this)->operator[](i);}
1588
1589 unsigned
1590 size() const
1591 {return elems_.size();}
1592
1593 vector<expr_result>::reverse_iterator
1594 begin()
1595 {return elems_.rbegin();}
1596
1597 const vector<expr_result>::reverse_iterator
1598 begin() const
1599 {return const_cast<expr_result_stack_type*>(this)->begin();}
1600
1601 vector<expr_result>::reverse_iterator
1602 end()
1603 {return elems_.rend();}
1604
1605 const vector<expr_result>::reverse_iterator
1606 end() const
1607 {return const_cast<expr_result_stack_type*>(this)->end();}
1608
1609 expr_result&
1610 front()
1611 {return elems_.back();}
1612
1613 const expr_result&
1614 front() const
1615 {return const_cast<expr_result_stack_type*>(this)->front();}
1616
1617 void
1618 push_front(expr_result e)
1619 {elems_.push_back(e);}
1620
1621 expr_result
1622 pop_front()
1623 {
1624 expr_result r = front();
1625 elems_.pop_back();
1626 return r;
1627 }
1628
1629 void
1630 erase(vector<expr_result>::reverse_iterator i)
1631 {elems_.erase(--i.base());}
1632
1633 void
1634 clear()
1635 {elems_.clear();}
1636}; // end class expr_result_stack_type
1637
1638/// Abstraction of the evaluation context of a dwarf expression.
1639struct dwarf_expr_eval_context
1640{
1641 expr_result accum;
1642 expr_result_stack_type stack;
1643 // Is set to true if the result of the expression that got evaluated
1644 // is a TLS address.
1645 bool set_tls_addr;
1646
1647 dwarf_expr_eval_context()
1648 : accum(/*is_const=*/false),
1649 set_tls_addr(false)
1650 {
1651 stack.push_front(expr_result(true));
1652 }
1653
1654 void
1655 reset()
1656 {
1657 stack.clear();
1658 stack.push_front(expr_result(true));
1659 accum = expr_result(false);
1660 set_tls_addr = false;
1661 }
1662
1663 /// Set a flag to to tell that the result of the expression that got
1664 /// evaluated is a TLS address.
1665 ///
1666 /// @param f true iff the result of the expression that got
1667 /// evaluated is a TLS address, false otherwise.
1668 void
1669 set_tls_address(bool f)
1670 {set_tls_addr = f;}
1671
1672 /// Getter for the flag that tells if the result of the expression
1673 /// that got evaluated is a TLS address.
1674 ///
1675 /// @return true iff the result of the expression that got evaluated
1676 /// is a TLS address.
1677 bool
1678 set_tls_address() const
1679 {return set_tls_addr;}
1680
1681 expr_result
1682 pop()
1683 {
1684 expr_result r = stack.front();
1685 stack.pop_front();
1686 return r;
1687 }
1688
1689 void
1690 push(const expr_result& v)
1691 {stack.push_front(v);}
1692};//end class dwarf_expr_eval_context
1693
1694// ---------------------------------------
1695// </location expression evaluation types>
1696// ---------------------------------------
1697
1698class reader;
1699
1700typedef shared_ptr<reader> reader_sptr;
1701
1702/// The DWARF reader used to build the ABI corpus from debug info in
1703/// DWARF format.
1704///
1705/// This type is to be instanciated
1706/// abigail::dwarf::reader::create().
1707class reader : public elf_based_reader
1708{
1709public:
1710
1711 /// A set of containers that contains one container per kind of @ref
1712 /// die_source. This allows to associate DIEs to things, depending
1713 /// on the source of the DIE.
1714 template <typename ContainerType>
1715 class die_source_dependant_container_set
1716 {
1717 ContainerType primary_debug_info_container_;
1718 ContainerType alt_debug_info_container_;
1719 ContainerType type_unit_container_;
1720
1721 public:
1722
1723 /// Getter for the container associated to DIEs coming from a
1724 /// given @ref die_source.
1725 ///
1726 /// @param source the die_source for which we want the container.
1727 ///
1728 /// @return the container that associates DIEs coming from @p
1729 /// source to something.
1730 ContainerType&
1731 get_container(die_source source)
1732 {
1733 ContainerType *result = 0;
1734 switch (source)
1735 {
1736 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1737 result = &primary_debug_info_container_;
1738 break;
1739 case ALT_DEBUG_INFO_DIE_SOURCE:
1740 result = &alt_debug_info_container_;
1741 break;
1742 case TYPE_UNIT_DIE_SOURCE:
1743 result = &type_unit_container_;
1744 break;
1745 case NO_DEBUG_INFO_DIE_SOURCE:
1746 case NUMBER_OF_DIE_SOURCES:
1748 }
1749 return *result;
1750 }
1751
1752 /// Getter for the container associated to DIEs coming from a
1753 /// given @ref die_source.
1754 ///
1755 /// @param source the die_source for which we want the container.
1756 ///
1757 /// @return the container that associates DIEs coming from @p
1758 /// source to something.
1759 const ContainerType&
1760 get_container(die_source source) const
1761 {
1762 return const_cast<die_source_dependant_container_set*>(this)->
1763 get_container(source);
1764 }
1765
1766 /// Getter for the container associated to DIEs coming from the
1767 /// same source as a given DIE.
1768 ///
1769 /// @param rdr the DWARF reader to consider.
1770 ///
1771 /// @param die the DIE which should have the same source as the
1772 /// source of the container we want.
1773 ///
1774 /// @return the container that associates DIEs coming from the
1775 /// same source as @p die.
1776 ContainerType&
1777 get_container(const reader& rdr, const Dwarf_Die *die)
1778 {
1779 const die_source source = rdr.get_die_source(die);
1780 return get_container(source);
1781 }
1782
1783 /// Getter for the container associated to DIEs coming from the
1784 /// same source as a given DIE.
1785 ///
1786 /// @param rdr the DWARF reader to consider.
1787 ///
1788 /// @param die the DIE which should have the same source as the
1789 /// source of the container we want.
1790 ///
1791 /// @return the container that associates DIEs coming from the
1792 /// same source as @p die.
1793 const ContainerType&
1794 get_container(const reader& rdr, const Dwarf_Die *die) const
1795 {
1796 return const_cast<die_source_dependant_container_set*>(this)->
1797 get_container(rdr, die);
1798 }
1799
1800 /// Clear the container set.
1801 void
1802 clear()
1803 {
1804 primary_debug_info_container_.clear();
1805 alt_debug_info_container_.clear();
1806 type_unit_container_.clear();
1807 }
1808 }; // end die_dependant_container_set
1809
1810 unsigned short dwarf_version_;
1811 Dwarf_Die* cur_tu_die_;
1812 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1813 // A set of maps (one per kind of die source) that associates a decl
1814 // string representation with the DIEs (offsets) representing that
1815 // decl.
1816 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1817 decl_die_repr_die_offsets_maps_;
1818 // A set of maps (one per kind of die source) that associates a type
1819 // string representation with the DIEs (offsets) representing that
1820 // type.
1821 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1822 type_die_repr_die_offsets_maps_;
1823 mutable die_source_dependant_container_set<die_istring_map_type>
1824 die_qualified_name_maps_;
1825 mutable die_source_dependant_container_set<die_istring_map_type>
1826 die_pretty_repr_maps_;
1827 mutable die_source_dependant_container_set<die_istring_map_type>
1828 die_pretty_type_repr_maps_;
1829 // A set of maps (one per kind of die source) that associates the
1830 // offset of a decl die to its corresponding decl artifact.
1831 mutable die_source_dependant_container_set<die_artefact_map_type>
1832 decl_die_artefact_maps_;
1833 // A set of maps (one per kind of die source) that associates the
1834 // offset of a type die to its corresponding type artifact.
1835 mutable die_source_dependant_container_set<die_artefact_map_type>
1836 type_die_artefact_maps_;
1837 /// A set of vectors (one per kind of die source) that associates
1838 /// the offset of a type DIE to the offset of its canonical DIE.
1839 mutable die_source_dependant_container_set<offset_offset_map_type>
1840 canonical_type_die_offsets_;
1841 /// A set of vectors (one per kind of die source) that associates
1842 /// the offset of a decl DIE to the offset of its canonical DIE.
1843 mutable die_source_dependant_container_set<offset_offset_map_type>
1844 canonical_decl_die_offsets_;
1845 /// A map that associates a function type representations to
1846 /// function types, inside a translation unit.
1847 mutable istring_fn_type_map_type per_tu_repr_to_fn_type_maps_;
1848 /// A map that associates a pair of DIE offsets to the result of the
1849 /// comparison of that pair.
1850 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1852 dwarf_offset_pair_hash> die_comparison_results_;
1853 // The set of types pair that have been canonical-type-propagated.
1854 mutable offset_pair_set_type propagated_types_;
1855 die_class_or_union_map_type die_wip_classes_map_;
1856 die_class_or_union_map_type alternate_die_wip_classes_map_;
1857 die_class_or_union_map_type type_unit_die_wip_classes_map_;
1858 die_function_type_map_type die_wip_function_types_map_;
1859 die_function_type_map_type alternate_die_wip_function_types_map_;
1860 die_function_type_map_type type_unit_die_wip_function_types_map_;
1861 die_function_decl_map_type die_function_with_no_symbol_map_;
1862 vector<type_base_sptr> types_to_canonicalize_;
1863 string_classes_or_unions_map decl_only_classes_map_;
1864 string_enums_map decl_only_enums_map_;
1865 die_tu_map_type die_tu_map_;
1866 translation_unit_sptr cur_tu_;
1867 scope_decl_sptr nil_scope_;
1868 scope_stack_type scope_stack_;
1869 offset_offset_map_type primary_die_parent_map_;
1870 // A map that associates each tu die to a vector of unit import
1871 // points, in the main debug info
1872 tu_die_imported_unit_points_map_type tu_die_imported_unit_points_map_;
1873 // A map that associates each tu die to a vector of unit import
1874 // points, in the alternate debug info
1875 tu_die_imported_unit_points_map_type alt_tu_die_imported_unit_points_map_;
1876 tu_die_imported_unit_points_map_type type_units_tu_die_imported_unit_points_map_;
1877 // A DIE -> parent map for DIEs coming from the alternate debug info
1878 // file.
1879 offset_offset_map_type alternate_die_parent_map_;
1880 offset_offset_map_type type_section_die_parent_map_;
1881 list<var_decl_sptr> var_decls_to_add_;
1882#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1883 bool debug_die_canonicalization_is_on_;
1884 bool use_canonical_die_comparison_;
1885#endif
1886 mutable size_t compare_count_;
1887 mutable size_t canonical_propagated_count_;
1888 mutable size_t cancelled_propagation_count_;
1889 mutable optional<bool> leverage_dwarf_factorization_;
1890
1891protected:
1892
1893 reader() = delete;
1894
1895 /// Constructor of reader.
1896 ///
1897 /// @param elf_path the path to the elf file the context is to be
1898 /// used for.
1899 ///
1900 /// @param debug_info_root_paths a vector of pointers to the path to
1901 /// the root directory under which the debug info is to be found for
1902 /// @p elf_path. Leave this empty if the debug info is not in a
1903 /// split file.
1904 ///
1905 /// @param environment the environment used by the current context.
1906 /// This environment contains resources needed by the DWARF reader and by
1907 /// the types and declarations that are to be created later. Note
1908 /// that ABI artifacts that are to be compared all need to be
1909 /// created within the same environment.
1910 ///
1911 /// Please also note that the life time of this environment object
1912 /// must be greater than the life time of the resulting @ref
1913 /// reader the context uses resources that are allocated in
1914 /// the environment.
1915 ///
1916 /// @param load_all_types if set to false only the types that are
1917 /// reachable from publicly exported declarations (of functions and
1918 /// variables) are read. If set to true then all types found in the
1919 /// debug information are loaded.
1920 ///
1921 /// @param linux_kernel_mode if set to true, then consider the special
1922 /// linux kernel symbol tables when determining if a symbol is
1923 /// exported or not.
1924 reader(const string& elf_path,
1925 const vector<char**>& debug_info_root_paths,
1926 environment& environment,
1927 bool load_all_types,
1928 bool linux_kernel_mode)
1929 : elf_based_reader(elf_path,
1931 environment)
1932 {
1933 initialize(load_all_types, linux_kernel_mode);
1934 }
1935
1936public:
1937
1938 /// Initializer of reader.
1939 ///
1940 /// Resets the reader so that it can be re-used to read another binary.
1941 ///
1942 /// @param load_all_types if set to false only the types that are
1943 /// reachable from publicly exported declarations (of functions and
1944 /// variables) are read. If set to true then all types found in the
1945 /// debug information are loaded.
1946 ///
1947 /// @param linux_kernel_mode if set to true, then consider the
1948 /// special linux kernel symbol tables when determining if a symbol
1949 /// is exported or not.
1950 void
1951 initialize(bool load_all_types, bool linux_kernel_mode)
1952 {
1953 dwarf_version_ = 0;
1954 cur_tu_die_ = 0;
1955 decl_die_repr_die_offsets_maps_.clear();
1956 type_die_repr_die_offsets_maps_.clear();
1957 die_qualified_name_maps_.clear();
1958 die_pretty_repr_maps_.clear();
1959 die_pretty_type_repr_maps_.clear();
1960 decl_die_artefact_maps_.clear();
1961 type_die_artefact_maps_.clear();
1962 canonical_type_die_offsets_.clear();
1963 canonical_decl_die_offsets_.clear();
1964 die_wip_classes_map_.clear();
1965 alternate_die_wip_classes_map_.clear();
1966 type_unit_die_wip_classes_map_.clear();
1967 die_wip_function_types_map_.clear();
1968 alternate_die_wip_function_types_map_.clear();
1969 type_unit_die_wip_function_types_map_.clear();
1970 die_function_with_no_symbol_map_.clear();
1971 types_to_canonicalize_.clear();
1972 decl_only_classes_map_.clear();
1973 die_tu_map_.clear();
1974 corpus().reset();
1975 corpus_group().reset();
1976 cur_tu_.reset();
1977 primary_die_parent_map_.clear();
1978 tu_die_imported_unit_points_map_.clear();
1979 alt_tu_die_imported_unit_points_map_.clear();
1980 type_units_tu_die_imported_unit_points_map_.clear();
1981 alternate_die_parent_map_.clear();
1982 type_section_die_parent_map_.clear();
1983 var_decls_to_add_.clear();
1984 clear_per_translation_unit_data();
1985 options().load_in_linux_kernel_mode = linux_kernel_mode;
1986 options().load_all_types = load_all_types;
1987#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1988 debug_die_canonicalization_is_on_ =
1989 env().debug_die_canonicalization_is_on();
1990 use_canonical_die_comparison_ = true;
1991#endif
1992 compare_count_ = 0;
1993 canonical_propagated_count_ = 0;
1994 cancelled_propagation_count_ = 0;
1995 load_in_linux_kernel_mode(linux_kernel_mode);
1996 }
1997
1998 /// Initializer of reader.
1999 ///
2000 /// Resets the reader so that it can be re-used to read another binary.
2001 ///
2002 /// @param elf_path the path to the new ELF file.
2003 ///
2004 /// @param debug_info_root_paths the vector of debug-info path to
2005 /// look for split debug info.
2006 ///
2007 /// @param load_all_types if set to false only the types that are
2008 /// reachable from publicly exported declarations (of functions and
2009 /// variables) are read. If set to true then all types found in the
2010 /// debug information are loaded.
2011 ///
2012 /// @param linux_kernel_mode if set to true, then consider the
2013 /// special linux kernel symbol tables when determining if a symbol
2014 /// is exported or not.
2015 void
2016 initialize(const string& elf_path,
2017 const vector<char**>& debug_info_root_paths,
2018 bool load_all_types,
2019 bool linux_kernel_mode)
2020 {
2021 reset(elf_path, debug_info_root_paths);
2022 initialize(load_all_types, linux_kernel_mode);
2023 }
2024
2025 /// Create an instance of DWARF Reader.
2026 ///
2027 /// @param elf_path the path to the ELF file to read from.
2028 ///
2029 /// @param debug_info_root_paths a vector of paths where to look up
2030 /// split debug info files.
2031 ///
2032 /// @param environment the environment to be used by the reader.
2033 ///
2034 /// @param load_all_types if set to false only the types that are
2035 /// reachable from publicly exported declarations (of functions and
2036 /// variables) are read. If set to true then all types found in the
2037 /// debug information are loaded.
2038 ///
2039 /// @param linux_kernel_mode if set to true, then consider the
2040 /// special linux kernel symbol tables when determining if a symbol
2041 /// is exported or not.
2042 static dwarf::reader_sptr
2043 create(const std::string& elf_path,
2044 const vector<char**>& debug_info_root_paths,
2045 environment& environment,
2046 bool load_all_types,
2047 bool linux_kernel_mode)
2048 {
2049 reader_sptr result(new reader(elf_path, debug_info_root_paths,
2050 environment, load_all_types,
2051 linux_kernel_mode));
2052 return result;
2053 }
2054
2055 /// Destructor of the @ref reader type.
2056 ~reader()
2057 {
2058 }
2059
2060 /// Read and analyze the ELF and DWARF information associated with
2061 /// the underlying ELF file and build an ABI corpus out of it.
2062 ///
2063 /// @param status output parameter. This is set to the status of
2064 /// the analysis of the debug info.
2065 ///
2066 /// @return the resulting ABI corpus.
2067 corpus_sptr
2068 read_corpus(status& status)
2069 {
2071
2072 // Load the generic ELF parts of the corpus.
2074
2076 || !(status & STATUS_OK))
2077 // Either we couldn't find ELF symbols or something went badly
2078 // wrong. There is nothing we can do with this ELF file. Bail
2079 // out.
2080 return corpus_sptr();
2081
2082 // If we couldn't find debug info from the elf path, then say it.
2083 if (dwarf_debug_info() == nullptr)
2085
2086 {
2087 string alt_di_path;
2088 if (refers_to_alt_debug_info(alt_di_path)
2091 }
2092
2093 if (// If debug info was found but not the required alternate debug
2094 // info ...
2097 // ... then we cannot handle the binary.
2098 return corpus_sptr();
2099
2100 // Read the variable and function descriptions from the debug info
2101 // we have, through the dwfl handle.
2102 corpus_sptr corp = read_debug_info_into_corpus();
2103
2104 status |= STATUS_OK;
2105
2106 return corp;
2107 }
2108
2109 /// Read an analyze the DWARF information.
2110 ///
2111 /// Construct an ABI corpus from it.
2112 ///
2113 /// This is a sub-routine of abigail::dwarf::reader::read_corpus().
2114 ///
2115 /// @return the resulting ABI corpus.
2116 corpus_sptr
2117 read_debug_info_into_corpus()
2118 {
2119 clear_per_corpus_data();
2120
2121 // First set some mundane properties of the corpus gathered from
2122 // ELF.
2123 corpus::origin origin = corpus()->get_origin();
2124 origin |= corpus::DWARF_ORIGIN;
2125 corpus()->set_origin(origin);
2126
2127 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2128 && !env().user_set_analyze_exported_interfaces_only())
2129 // So we are looking at the Linux Kernel and the user has not set
2130 // any particular option regarding the amount of types to analyse.
2131 // In that case, we need to only analyze types that are reachable
2132 // from exported interfaces otherwise we get such a massive amount
2133 // of type DIEs to look at that things are just too slow down the
2134 // road.
2135 env().analyze_exported_interfaces_only(true);
2136
2137 corpus()->set_soname(dt_soname());
2138 corpus()->set_needed(dt_needed());
2139 corpus()->set_architecture_name(elf_architecture());
2140 // Set symbols information to the corpus.
2141 corpus()->set_symtab(symtab());
2142
2143 // Get out now if no debug info is found or if the symbol table is
2144 // empty.
2145 if (!dwarf_debug_info()
2146 || !corpus()->get_symtab()->has_symbols())
2147 return corpus();
2148
2149 uint8_t address_size = 0;
2150 size_t header_size = 0;
2151
2152#ifdef WITH_DEBUG_SELF_COMPARISON
2153 if (env().self_comparison_debug_is_on())
2154 env().set_self_comparison_debug_input(corpus());
2155#endif
2156
2157 // Walk all the DIEs of the debug info to build a DIE -> parent map
2158 // useful for get_die_parent() to work.
2159 {
2160 tools_utils::timer t;
2161 if (do_log())
2162 {
2163 cerr << "building die -> parent maps ...";
2164 t.start();
2165 }
2166
2167 build_die_parent_maps();
2168
2169 if (do_log())
2170 {
2171 t.stop();
2172 cerr << " DONE@" << corpus()->get_path()
2173 << ":"
2174 << t
2175 << "\n";
2176 }
2177 }
2178
2179 env().canonicalization_is_done(false);
2180
2181 {
2182 tools_utils::timer t;
2183 if (do_log())
2184 {
2185 cerr << "building the libabigail internal representation ...";
2186 t.start();
2187 }
2188 // And now walk all the DIEs again to build the libabigail IR.
2189 Dwarf_Half dwarf_vers = 0;
2190 for (Dwarf_Off offset = 0, next_offset = 0;
2191 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
2192 offset, &next_offset, &header_size,
2193 &dwarf_vers, NULL, &address_size, NULL,
2194 NULL, NULL) == 0);
2195 offset = next_offset)
2196 {
2197 Dwarf_Off die_offset = offset + header_size;
2198 Dwarf_Die unit;
2199 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
2200 die_offset, &unit)
2201 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2202 continue;
2203
2204 dwarf_version(dwarf_vers);
2205
2206 address_size *= 8;
2207
2208 // Build a translation_unit IR node from cu; note that cu must
2209 // be a DW_TAG_compile_unit die.
2210 translation_unit_sptr ir_node =
2211 build_translation_unit_and_add_to_ir(*this, &unit, address_size);
2212 ABG_ASSERT(ir_node);
2213 }
2214 if (do_log())
2215 {
2216 t.stop();
2217 cerr << " DONE@" << corpus()->get_path()
2218 << ":"
2219 << t
2220 << "\n";
2221
2222 cerr << "Number of aggregate types compared: "
2223 << compare_count_ << "\n"
2224 << "Number of canonical types propagated: "
2225 << canonical_propagated_count_ << "\n"
2226 << "Number of cancelled propagated canonical types:"
2227 << cancelled_propagation_count_ << "\n";
2228 }
2229 }
2230
2231 {
2232 tools_utils::timer t;
2233 if (do_log())
2234 {
2235 cerr << "resolving declaration only classes ...";
2236 t.start();
2237 }
2238 resolve_declaration_only_classes();
2239 if (do_log())
2240 {
2241 t.stop();
2242 cerr << " DONE@" << corpus()->get_path()
2243 << ":"
2244 << t
2245 <<"\n";
2246 }
2247 }
2248
2249 {
2250 tools_utils::timer t;
2251 if (do_log())
2252 {
2253 cerr << "resolving declaration only enums ...";
2254 t.start();
2255 }
2256 resolve_declaration_only_enums();
2257 if (do_log())
2258 {
2259 t.stop();
2260 cerr << " DONE@" << corpus()->get_path()
2261 << ":"
2262 << t
2263 <<"\n";
2264 }
2265 }
2266
2267 {
2268 tools_utils::timer t;
2269 if (do_log())
2270 {
2271 cerr << "fixing up functions with linkage name but "
2272 << "no advertised underlying symbols ....";
2273 t.start();
2274 }
2275 fixup_functions_with_no_symbols();
2276 if (do_log())
2277 {
2278 t.stop();
2279 cerr << " DONE@" << corpus()->get_path()
2280 <<":"
2281 << t
2282 <<"\n";
2283 }
2284 }
2285
2286 /// Now, look at the types that needs to be canonicalized after the
2287 /// translation has been constructed (which is just now) and
2288 /// canonicalize them.
2289 ///
2290 /// These types need to be constructed at the end of the translation
2291 /// unit reading phase because some types are modified by some DIEs
2292 /// even after the principal DIE describing the type has been read;
2293 /// this happens for clones of virtual destructors (for instance) or
2294 /// even for some static data members. We need to do that for types
2295 /// are in the alternate debug info section and for types that in
2296 /// the main debug info section.
2297 {
2298 tools_utils::timer t;
2299 if (do_log())
2300 {
2301 cerr << "perform late type canonicalizing ...\n";
2302 t.start();
2303 }
2304
2305 perform_late_type_canonicalizing();
2306 if (do_log())
2307 {
2308 t.stop();
2309 cerr << "late type canonicalizing DONE@"
2310 << corpus()->get_path()
2311 << ":"
2312 << t
2313 << "\n";
2314 }
2315 }
2316
2317 env().canonicalization_is_done(true);
2318
2319 {
2320 tools_utils::timer t;
2321 if (do_log())
2322 {
2323 cerr << "sort functions and variables ...";
2324 t.start();
2325 }
2326 corpus()->sort_functions();
2327 corpus()->sort_variables();
2328 if (do_log())
2329 {
2330 t.stop();
2331 cerr << " DONE@" << corpus()->get_path()
2332 << ":"
2333 << t
2334 <<" \n";
2335 }
2336 }
2337
2338 return corpus();
2339 }
2340
2341 /// Clear the data that is relevant only for the current translation
2342 /// unit being read. The rest of the data is relevant for the
2343 /// entire ABI corpus.
2344 void
2345 clear_per_translation_unit_data()
2346 {
2347 while (!scope_stack().empty())
2348 scope_stack().pop();
2349 var_decls_to_re_add_to_tree().clear();
2350 per_tu_repr_to_fn_type_maps().clear();
2351 }
2352
2353 /// Clear the data that is relevant for the current corpus being
2354 /// read.
2355 void
2356 clear_per_corpus_data()
2357 {
2358 die_qualified_name_maps_.clear();
2359 die_pretty_repr_maps_.clear();
2360 die_pretty_type_repr_maps_.clear();
2361 clear_types_to_canonicalize();
2362 }
2363
2364 /// Getter for the current environment.
2365 ///
2366 /// @return the current environment.
2367 environment&
2368 env()
2369 {return options().env;}
2370
2371 /// Getter for the current environment.
2372 ///
2373 /// @return the current environment.
2374 const environment&
2375 env() const
2376 {return const_cast<reader*>(this)->env();}
2377
2378 /// Getter for the flag that tells us if we are dropping functions
2379 /// and variables that have undefined symbols.
2380 ///
2381 /// @return true iff we are dropping functions and variables that have
2382 /// undefined symbols.
2383 bool
2384 drop_undefined_syms() const
2385 {return options().drop_undefined_syms;}
2386
2387 /// Setter for the flag that tells us if we are dropping functions
2388 /// and variables that have undefined symbols.
2389 ///
2390 /// @param f the new value of the flag.
2391 void
2392 drop_undefined_syms(bool f)
2393 {options().drop_undefined_syms = f;}
2394
2395 /// Getter of the DWARF version.
2396 unsigned short
2397 dwarf_version() const
2398 {return dwarf_version_;}
2399
2400 void
2401 dwarf_version(unsigned short v)
2402 {dwarf_version_ = v;}
2403
2404 /// Return the ELF descriptor used for DWARF access.
2405 ///
2406 /// This can be the same as reader::elf_handle() above, if the
2407 /// DWARF info is in the same ELF file as the one of the binary we
2408 /// are analizing. It is different if e.g, the debug info is split
2409 /// from the ELF file we are analizing.
2410 ///
2411 /// @return a pointer to the ELF descriptor used to access debug
2412 /// info.
2413 Elf*
2414 dwarf_elf_handle() const
2415 {return dwarf_getelf(const_cast<Dwarf*>(dwarf_debug_info()));}
2416
2417 /// Test if the debug information is in a separate ELF file wrt the
2418 /// main ELF file of the program (application or shared library) we
2419 /// are analizing.
2420 ///
2421 /// @return true if the debug information is in a separate ELF file
2422 /// compared to the main ELF file of the program (application or
2423 /// shared library) that we are looking at.
2424 bool
2425 dwarf_is_splitted() const
2426 {return dwarf_elf_handle() != elf_handle();}
2427
2428 /// Return the correct debug info, depending on the DIE source we
2429 /// are looking at.
2430 ///
2431 /// @param source the DIE source to consider.
2432 ///
2433 /// @return the right debug info, depending on @p source.
2434 const Dwarf*
2435 dwarf_per_die_source(die_source source) const
2436 {
2437 const Dwarf *result = 0;
2438 switch(source)
2439 {
2440 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2441 case TYPE_UNIT_DIE_SOURCE:
2442 result = dwarf_debug_info();
2443 break;
2444 case ALT_DEBUG_INFO_DIE_SOURCE:
2445 result = alternate_dwarf_debug_info();
2446 break;
2447 case NO_DEBUG_INFO_DIE_SOURCE:
2448 case NUMBER_OF_DIE_SOURCES:
2450 }
2451 return result;
2452 }
2453
2454 /// Return the path to the ELF path we are reading.
2455 ///
2456 /// @return the elf path.
2457 const string&
2458 elf_path() const
2459 {return corpus_path();}
2460
2461 const Dwarf_Die*
2462 cur_tu_die() const
2463 {return cur_tu_die_;}
2464
2465 void
2466 cur_tu_die(Dwarf_Die* cur_tu_die)
2467 {cur_tu_die_ = cur_tu_die;}
2468
2469 dwarf_expr_eval_context&
2470 dwarf_expr_eval_ctxt() const
2471 {return dwarf_expr_eval_context_;}
2472
2473 /// Getter of the maps set that associates a representation of a
2474 /// decl DIE to a vector of offsets of DIEs having that representation.
2475 ///
2476 /// @return the maps set that associates a representation of a decl
2477 /// DIE to a vector of offsets of DIEs having that representation.
2478 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2479 decl_die_repr_die_offsets_maps() const
2480 {return decl_die_repr_die_offsets_maps_;}
2481
2482 /// Getter of the maps set that associates a representation of a
2483 /// decl DIE to a vector of offsets of DIEs having that representation.
2484 ///
2485 /// @return the maps set that associates a representation of a decl
2486 /// DIE to a vector of offsets of DIEs having that representation.
2487 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2488 decl_die_repr_die_offsets_maps()
2489 {return decl_die_repr_die_offsets_maps_;}
2490
2491 /// Getter of the maps set that associate a representation of a type
2492 /// DIE to a vector of offsets of DIEs having that representation.
2493 ///
2494 /// @return the maps set that associate a representation of a type
2495 /// DIE to a vector of offsets of DIEs having that representation.
2496 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2497 type_die_repr_die_offsets_maps() const
2498 {return type_die_repr_die_offsets_maps_;}
2499
2500 /// Getter of the maps set that associate a representation of a type
2501 /// DIE to a vector of offsets of DIEs having that representation.
2502 ///
2503 /// @return the maps set that associate a representation of a type
2504 /// DIE to a vector of offsets of DIEs having that representation.
2505 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2506 type_die_repr_die_offsets_maps()
2507 {return type_die_repr_die_offsets_maps_;}
2508
2509
2510 /// Compute the offset of the canonical DIE of a given DIE.
2511 ///
2512 /// @param die the DIE to consider.
2513 ///
2514 /// @param canonical_die_offset out parameter. This is set to the
2515 /// resulting canonical DIE that was computed.
2516 ///
2517 /// @param die_as_type if yes, it means @p die has to be considered
2518 /// as a type.
2519 void
2520 compute_canonical_die_offset(const Dwarf_Die *die,
2521 Dwarf_Off &canonical_die_offset,
2522 bool die_as_type) const
2523 {
2524 offset_offset_map_type &canonical_dies =
2525 die_as_type
2526 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
2527 get_container(*this, die)
2528 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
2529 get_container(*this, die);
2530
2531 Dwarf_Die canonical_die;
2532 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2533
2534 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2535 }
2536
2537 /// Compute (find) the canonical DIE of a given DIE.
2538 ///
2539 /// @param die the DIE to consider.
2540 ///
2541 /// @param canonical_dies the vector in which the canonical dies ar
2542 /// stored. The index of each element is the offset of the DIE we
2543 /// want the canonical DIE for. And the value of the element at
2544 /// that index is the canonical DIE offset we are looking for.
2545 ///
2546 /// @param canonical_die_offset out parameter. This is set to the
2547 /// resulting canonical DIE that was computed.
2548 ///
2549 /// @param die_as_type if yes, it means @p die has to be considered
2550 /// as a type.
2551 void
2552 compute_canonical_die(const Dwarf_Die *die,
2553 offset_offset_map_type& canonical_dies,
2554 Dwarf_Die &canonical_die,
2555 bool die_as_type) const
2556 {
2557 const die_source source = get_die_source(die);
2558
2559 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2560
2561 compute_canonical_die(die_offset, source,
2562 canonical_dies,
2563 canonical_die, die_as_type);
2564 }
2565
2566 /// Compute (find) the canonical DIE of a given DIE.
2567 ///
2568 /// @param die_offset the offset of the DIE to consider.
2569 ///
2570 /// @param source the source of the DIE to consider.
2571 ///
2572 /// @param canonical_dies the vector in which the canonical dies ar
2573 /// stored. The index of each element is the offset of the DIE we
2574 /// want the canonical DIE for. And the value of the element at
2575 /// that index is the canonical DIE offset we are looking for.
2576 ///
2577 /// @param canonical_die_offset out parameter. This is set to the
2578 /// resulting canonical DIE that was computed.
2579 ///
2580 /// @param die_as_type if yes, it means @p die has to be considered
2581 /// as a type.
2582 void
2583 compute_canonical_die(Dwarf_Off die_offset,
2584 die_source source,
2585 offset_offset_map_type& canonical_dies,
2586 Dwarf_Die &canonical_die,
2587 bool die_as_type) const
2588 {
2589 // The map that associates the string representation of 'die'
2590 // with a vector of offsets of potentially equivalent DIEs.
2592 die_as_type
2593 ? (const_cast<reader*>(this)->
2594 type_die_repr_die_offsets_maps().get_container(source))
2595 : (const_cast<reader*>(this)->
2596 decl_die_repr_die_offsets_maps().get_container(source));
2597
2598 Dwarf_Die die;
2599 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2600 die_offset, &die));
2601
2602 // The variable repr is the the string representation of 'die'.
2603 //
2604 // Even if die_as_type is true -- which means that 'die' is said
2605 // to be considered as a type -- we always consider a
2606 // DW_TAG_subprogram DIE as a decl here, as far as its string
2607 // representation is concerned.
2608 interned_string name =
2609 (die_as_type)
2610 ? get_die_pretty_type_representation(&die, /*where=*/0)
2611 : get_die_pretty_representation(&die, /*where=*/0);
2612
2613 Dwarf_Off canonical_die_offset = 0;
2614 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2615 if (i == map.end())
2616 {
2617 dwarf_offsets_type offsets;
2618 offsets.push_back(die_offset);
2619 map[name] = offsets;
2620 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2621 get_die_from_offset(source, die_offset, &canonical_die);
2622 return;
2623 }
2624
2625 Dwarf_Off cur_die_offset;
2626 Dwarf_Die potential_canonical_die;
2627 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2628 o != i->second.end();
2629 ++o)
2630 {
2631 cur_die_offset = *o;
2632 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2633 if (compare_dies(*this, &die, &potential_canonical_die,
2634 /*update_canonical_dies_on_the_fly=*/false))
2635 {
2636 canonical_die_offset = cur_die_offset;
2637 set_canonical_die_offset(canonical_dies, die_offset,
2638 canonical_die_offset);
2639 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2640 return;
2641 }
2642 }
2643
2644 canonical_die_offset = die_offset;
2645 i->second.push_back(die_offset);
2646 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2647 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2648 }
2649
2650 /// Getter of the canonical DIE of a given DIE.
2651 ///
2652 /// @param die the DIE to consider.
2653 ///
2654 /// @param canonical_die output parameter. Is set to the resulting
2655 /// canonical die, if this function returns true.
2656 ///
2657 /// @param where the offset of the logical DIE we are supposed to be
2658 /// calling this function from. If set to zero this means this is
2659 /// to be ignored.
2660 ///
2661 /// @param die_as_type if set to yes, it means @p die is to be
2662 /// considered as a type DIE.
2663 ///
2664 /// @return true iff a canonical DIE was found for @p die.
2665 bool
2666 get_canonical_die(const Dwarf_Die *die,
2667 Dwarf_Die &canonical_die,
2668 size_t where,
2669 bool die_as_type)
2670 {
2671 const die_source source = get_die_source(die);
2672
2673 offset_offset_map_type &canonical_dies =
2674 die_as_type
2675 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
2676 get_container(source)
2677 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
2678 get_container(source);
2679
2680 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2681 if (Dwarf_Off canonical_die_offset =
2682 get_canonical_die_offset(canonical_dies, die_offset))
2683 {
2684 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2685 return true;
2686 }
2687
2688 // The map that associates the string representation of 'die'
2689 // with a vector of offsets of potentially equivalent DIEs.
2691 die_as_type
2692 ? (const_cast<reader*>(this)->
2693 type_die_repr_die_offsets_maps().get_container(*this, die))
2694 : (const_cast<reader*>(this)->
2695 decl_die_repr_die_offsets_maps().get_container(*this, die));
2696
2697 // The variable repr is the the string representation of 'die'.
2698 //
2699 // Even if die_as_type is true -- which means that 'die' is said
2700 // to be considered as a type -- we always consider a
2701 // DW_TAG_subprogram DIE as a decl here, as far as its string
2702 // representation is concerned.
2703 interned_string name =
2704 (die_as_type /*&& dwarf_tag(die) != DW_TAG_subprogram*/)
2705 ? get_die_pretty_type_representation(die, where)
2706 : get_die_pretty_representation(die, where);
2707
2708 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2709 if (i == map.end())
2710 return false;
2711
2712 Dwarf_Off cur_die_offset;
2713 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2714 o != i->second.end();
2715 ++o)
2716 {
2717 cur_die_offset = *o;
2718 get_die_from_offset(source, cur_die_offset, &canonical_die);
2719 // compare die and canonical_die.
2720 if (compare_dies_during_canonicalization(const_cast<reader&>(*this),
2721 die, &canonical_die,
2722 /*update_canonical_dies_on_the_fly=*/true))
2723 {
2724 set_canonical_die_offset(canonical_dies,
2725 die_offset,
2726 cur_die_offset);
2727 return true;
2728 }
2729 }
2730
2731 return false;
2732 }
2733
2734 /// Retrieve the canonical DIE of a given DIE.
2735 ///
2736 /// The canonical DIE is a DIE that is structurally equivalent to
2737 /// this one.
2738 ///
2739 /// Note that this function caches the canonical DIE that was
2740 /// computed. Subsequent invocations of this function on the same
2741 /// DIE return the same cached DIE.
2742 ///
2743 /// @param die the DIE to get a canonical type for.
2744 ///
2745 /// @param canonical_die the resulting canonical DIE.
2746 ///
2747 /// @param where the offset of the logical DIE we are supposed to be
2748 /// calling this function from. If set to zero this means this is
2749 /// to be ignored.
2750 ///
2751 /// @param die_as_type if true, consider DIE is a type.
2752 ///
2753 /// @return true if an *existing* canonical DIE was found.
2754 /// Otherwise, @p die is considered as being a canonical DIE for
2755 /// itself. @p canonical_die is thus set to the canonical die in
2756 /// either cases.
2757 bool
2758 get_or_compute_canonical_die(const Dwarf_Die* die,
2759 Dwarf_Die& canonical_die,
2760 size_t where,
2761 bool die_as_type) const
2762 {
2763 const die_source source = get_die_source(die);
2764
2765 offset_offset_map_type &canonical_dies =
2766 die_as_type
2767 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
2768 get_container(source)
2769 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
2770 get_container(source);
2771
2772 Dwarf_Off initial_die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2773
2774 if (Dwarf_Off canonical_die_offset =
2775 get_canonical_die_offset(canonical_dies,
2776 initial_die_offset))
2777 {
2778 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2779 return true;
2780 }
2781
2782 if (!is_type_die_to_be_canonicalized(die))
2783 return false;
2784
2785 // The map that associates the string representation of 'die'
2786 // with a vector of offsets of potentially equivalent DIEs.
2788 die_as_type
2789 ? (const_cast<reader*>(this)->
2790 type_die_repr_die_offsets_maps().get_container(*this, die))
2791 : (const_cast<reader*>(this)->
2792 decl_die_repr_die_offsets_maps().get_container(*this, die));
2793
2794 // The variable repr is the the string representation of 'die'.
2795 //
2796 // Even if die_as_type is true -- which means that 'die' is said
2797 // to be considered as a type -- we always consider a
2798 // DW_TAG_subprogram DIE as a decl here, as far as its string
2799 // representation is concerned.
2800 interned_string name =
2801 (die_as_type)
2802 ? get_die_pretty_type_representation(die, where)
2803 : get_die_pretty_representation(die, where);
2804
2805 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2806 if (i == map.end())
2807 {
2808 dwarf_offsets_type offsets;
2809 offsets.push_back(initial_die_offset);
2810 map[name] = offsets;
2811 get_die_from_offset(source, initial_die_offset, &canonical_die);
2812 set_canonical_die_offset(canonical_dies,
2813 initial_die_offset,
2814 initial_die_offset);
2815 return false;
2816 }
2817
2818 // walk i->second without any iterator (using a while loop rather
2819 // than a for loop) because compare_dies might add new content to
2820 // the end of the i->second vector during the walking.
2821 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2822 while (n < s)
2823 {
2824 Dwarf_Off die_offset = i->second[n];
2825 get_die_from_offset(source, die_offset, &canonical_die);
2826 // compare die and canonical_die.
2827 if (compare_dies_during_canonicalization(const_cast<reader&>(*this),
2828 die, &canonical_die,
2829 /*update_canonical_dies_on_the_fly=*/true))
2830 {
2831 set_canonical_die_offset(canonical_dies,
2832 initial_die_offset,
2833 die_offset);
2834 return true;
2835 }
2836 ++n;
2837 }
2838
2839 // We didn't find a canonical DIE for 'die'. So let's consider
2840 // that it is its own canonical DIE.
2841 get_die_from_offset(source, initial_die_offset, &canonical_die);
2842 i->second.push_back(initial_die_offset);
2843 set_canonical_die_offset(canonical_dies,
2844 initial_die_offset,
2845 initial_die_offset);
2846
2847 return false;
2848 }
2849
2850 /// Get the source of the DIE.
2851 ///
2852 /// The function returns an enumerator value saying if the DIE comes
2853 /// from the .debug_info section of the primary debug info file, the
2854 /// .debug_info section of the alternate debug info file, or the
2855 /// .debug_types section.
2856 ///
2857 /// @param die the DIE to get the source of.
2858 ///
2859 /// @return the source of the DIE if it could be determined,
2860 /// NO_DEBUG_INFO_DIE_SOURCE otherwise.
2862 get_die_source(const Dwarf_Die *die) const
2863 {
2864 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2865 ABG_ASSERT(die);
2866 ABG_ASSERT(get_die_source(*die, source));
2867 return source;
2868 }
2869
2870 /// Get the source of the DIE.
2871 ///
2872 /// The function returns an enumerator value saying if the DIE comes
2873 /// from the .debug_info section of the primary debug info file, the
2874 /// .debug_info section of the alternate debug info file, or the
2875 /// .debug_types section.
2876 ///
2877 /// @param die the DIE to get the source of.
2878 ///
2879 /// @param source out parameter. The function sets this parameter
2880 /// to the source of the DIE @p iff it returns true.
2881 ///
2882 /// @return true iff the source of the DIE could be determined and
2883 /// returned.
2884 bool
2885 get_die_source(const Dwarf_Die &die, die_source &source) const
2886 {
2887 Dwarf_Die cu_die;
2888 Dwarf_Die cu_kind;
2889 uint8_t address_size = 0, offset_size = 0;
2890 if (!dwarf_diecu(const_cast<Dwarf_Die*>(&die),
2891 &cu_die, &address_size,
2892 &offset_size))
2893 return false;
2894
2895 Dwarf_Half version = 0;
2896 Dwarf_Off abbrev_offset = 0;
2897 uint64_t type_signature = 0;
2898 Dwarf_Off type_offset = 0;
2899 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2900 &version, &abbrev_offset,
2901 &address_size, &offset_size,
2902 &type_signature, &type_offset))
2903 return false;
2904
2905 int tag = dwarf_tag(&cu_kind);
2906
2907 if (tag == DW_TAG_compile_unit
2908 || tag == DW_TAG_partial_unit)
2909 {
2910 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2911 if (dwarf_debug_info() == die_dwarf)
2912 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2913 else if (alternate_dwarf_debug_info() == die_dwarf)
2914 source = ALT_DEBUG_INFO_DIE_SOURCE;
2915 else
2917 }
2918 else if (tag == DW_TAG_type_unit)
2919 source = TYPE_UNIT_DIE_SOURCE;
2920 else
2921 return false;
2922
2923 return true;
2924 }
2925
2926 /// Getter for the DIE designated by an offset.
2927 ///
2928 /// @param source the source of the DIE to get.
2929 ///
2930 /// @param offset the offset of the DIE to get.
2931 ///
2932 /// @param die the resulting DIE. The pointer has to point to an
2933 /// allocated memory region.
2934 void
2935 get_die_from_offset(die_source source, Dwarf_Off offset, Dwarf_Die *die) const
2936 {
2937 if (source == TYPE_UNIT_DIE_SOURCE)
2938 ABG_ASSERT(dwarf_offdie_types(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2939 offset, die));
2940 else
2941 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2942 offset, die));
2943 }
2944
2945public:
2946
2947 /// Add an entry to the relevant die->decl map.
2948 ///
2949 /// @param die the DIE to add the the map.
2950 ///
2951 /// @param decl the decl to consider.
2952 ///
2953 /// @param where_offset where in the DIE stream we logically are.
2954 ///
2955 /// @param do_associate_by_repr if true then this function
2956 /// associates the representation string of @p die with the
2957 /// declaration @p decl, in a corpus-wide manner. That is, in the
2958 /// entire current corpus, there is going to be just one declaration
2959 /// associated with a DIE of the string representation of @p die.
2960 ///
2961 /// @param do_associate_by_repr_per_tu if true, then this function
2962 /// associates the representation string of @p die with the
2963 /// declaration @p decl in a translation unit wide manner. That is,
2964 /// in the entire current translation unit, there is going to be
2965 /// just one declaration associated with a DIE of the string
2966 /// representation of @p die.
2967 void
2968 associate_die_to_decl(Dwarf_Die* die,
2969 decl_base_sptr decl,
2970 size_t where_offset,
2971 bool do_associate_by_repr = false)
2972 {
2973 const die_source source = get_die_source(die);
2974
2976 decl_die_artefact_maps().get_container(source);
2977
2978 size_t die_offset;
2979 if (do_associate_by_repr)
2980 {
2981 Dwarf_Die equiv_die;
2982 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2983 /*die_as_type=*/false))
2984 return;
2985 die_offset = dwarf_dieoffset(&equiv_die);
2986 }
2987 else
2988 die_offset = dwarf_dieoffset(die);
2989
2990 m[die_offset] = decl;
2991 }
2992
2993 /// Lookup the decl for a given DIE.
2994 ///
2995 /// The returned decl is either the decl of the DIE that as the
2996 /// exact offset @p die_offset
2997 /// die_offset, or
2998 /// give
2999 ///
3000 /// @param die_offset the offset of the DIE to consider.
3001 ///
3002 /// @param source where the DIE represented by @p die_offset comes
3003 /// from.
3004 ///
3005 /// Note that "alternate debug info sections" is a GNU extension as
3006 /// of DWARF4 and is described at
3007 /// http://www.dwarfstd.org/ShowIssue.php?issue=120604.1
3008 ///
3009 /// @return the resulting decl, or null if no decl is associated to
3010 /// the DIE represented by @p die_offset.
3011 decl_base_sptr
3012 lookup_decl_from_die_offset(Dwarf_Off die_offset, die_source source)
3013 {
3014 decl_base_sptr result =
3015 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3016 /*die_as_type=*/false));
3017
3018 return result;
3019 }
3020
3021 /// Get the qualified name of a given DIE.
3022 ///
3023 /// If the name of the DIE was already computed before just return
3024 /// that name from a cache. Otherwise, build the name, cache it and
3025 /// return it.
3026 ///
3027 /// @param die the DIE to consider.
3028 ///
3029 /// @param where_offset where in the DIE stream we logically are.
3030 ///
3031 /// @return the interned string representing the qualified name of
3032 /// @p die.
3033 interned_string
3034 get_die_qualified_name(Dwarf_Die *die, size_t where_offset)
3035 {
3036 ABG_ASSERT(die);
3038 die_qualified_name_maps_.get_container(*this, die);
3039
3040 size_t die_offset = dwarf_dieoffset(die);
3041 die_istring_map_type::const_iterator i = map.find(die_offset);
3042
3043 if (i == map.end())
3044 {
3045 reader& rdr = *const_cast<reader*>(this);
3046 string qualified_name = die_qualified_name(rdr, die, where_offset);
3047 interned_string istr = env().intern(qualified_name);
3048 map[die_offset] = istr;
3049 return istr;
3050 }
3051
3052 return i->second;
3053 }
3054
3055 /// Get the qualified name of a given DIE.
3056 ///
3057 /// If the name of the DIE was already computed before just return
3058 /// that name from a cache. Otherwise, build the name, cache it and
3059 /// return it.
3060 ///
3061 /// @param die the DIE to consider.
3062 ///
3063 /// @param where_offset where in the DIE stream we logically are.
3064 ///
3065 /// @return the interned string representing the qualified name of
3066 /// @p die.
3067 interned_string
3068 get_die_qualified_name(Dwarf_Die *die, size_t where_offset) const
3069 {
3070 return const_cast<reader*>(this)->
3071 get_die_qualified_name(die, where_offset);
3072 }
3073
3074 /// Get the qualified name of a given DIE which is considered to be
3075 /// the DIE for a type.
3076 ///
3077 /// For instance, for a DW_TAG_subprogram DIE, this function
3078 /// computes the name of the function *type* that corresponds to the
3079 /// function.
3080 ///
3081 /// If the name of the DIE was already computed before just return
3082 /// that name from a cache. Otherwise, build the name, cache it and
3083 /// return it.
3084 ///
3085 /// @param die the DIE to consider.
3086 ///
3087 /// @param where_offset where in the DIE stream we logically are.
3088 ///
3089 /// @return the interned string representing the qualified name of
3090 /// @p die.
3091 interned_string
3092 get_die_qualified_type_name(const Dwarf_Die *die, size_t where_offset) const
3093 {
3094 ABG_ASSERT(die);
3095
3096 // The name of the translation unit die is "".
3097 if (die == cur_tu_die())
3098 return env().intern("");
3099
3101 die_qualified_name_maps_.get_container(*const_cast<reader*>(this),
3102 die);
3103
3104 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3105 die_istring_map_type::const_iterator i =
3106 map.find(die_offset);
3107
3108 if (i == map.end())
3109 {
3110 reader& rdr = *const_cast<reader*>(this);
3111 string qualified_name;
3112 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
3113 if ((tag == DW_TAG_structure_type
3114 || tag == DW_TAG_class_type
3115 || tag == DW_TAG_union_type)
3116 && die_is_anonymous(die))
3117 {
3118 location l = die_location(*this, die);
3119 qualified_name = l ? l.expand() : "noloc";
3120 qualified_name = "unnamed-at-" + qualified_name;
3121 }
3122 else
3123 qualified_name =
3124 die_qualified_type_name(rdr, die, where_offset);
3125
3126 interned_string istr = env().intern(qualified_name);
3127 map[die_offset] = istr;
3128 return istr;
3129 }
3130
3131 return i->second;
3132 }
3133
3134 /// Get the pretty representation of a DIE that represents a type.
3135 ///
3136 /// For instance, for the DW_TAG_subprogram, this function computes
3137 /// the pretty representation of the type of the function, not the
3138 /// pretty representation of the function declaration.
3139 ///
3140 /// Once the pretty representation is computed, it's stored in a
3141 /// cache. Subsequent invocations of this function on the same DIE
3142 /// will yield the cached name.
3143 ///
3144 /// @param die the DIE to consider.
3145 ///
3146 /// @param where_offset where in the DIE stream we logically are.
3147 ///
3148 /// @return the interned_string that represents the pretty
3149 /// representation.
3150 interned_string
3151 get_die_pretty_type_representation(const Dwarf_Die *die,
3152 size_t where_offset) const
3153 {
3154 ABG_ASSERT(die);
3156 die_pretty_type_repr_maps_.get_container(*const_cast<reader*>(this),
3157 die);
3158
3159 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3160 die_istring_map_type::const_iterator i = map.find(die_offset);
3161
3162 if (i == map.end())
3163 {
3164 reader& rdr = *const_cast<reader*>(this);
3165 string pretty_representation =
3166 die_pretty_print_type(rdr, die, where_offset);
3167 interned_string istr = env().intern(pretty_representation);
3168 map[die_offset] = istr;
3169 return istr;
3170 }
3171
3172 return i->second;
3173 }
3174
3175 /// Get the pretty representation of a DIE.
3176 ///
3177 /// Once the pretty representation is computed, it's stored in a
3178 /// cache. Subsequent invocations of this function on the same DIE
3179 /// will yield the cached name.
3180 ///
3181 /// @param die the DIE to consider.
3182 ///
3183 /// @param where_offset where in the DIE stream we logically are.
3184 ///
3185 /// @return the interned_string that represents the pretty
3186 /// representation.
3187 interned_string
3188 get_die_pretty_representation(const Dwarf_Die *die, size_t where_offset) const
3189 {
3190 ABG_ASSERT(die);
3191
3193 die_pretty_repr_maps_.get_container(*const_cast<reader*>(this),
3194 die);
3195
3196 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3197 die_istring_map_type::const_iterator i = map.find(die_offset);
3198
3199 if (i == map.end())
3200 {
3201 reader& rdr = *const_cast<reader*>(this);
3202 string pretty_representation =
3203 die_pretty_print(rdr, die, where_offset);
3204 interned_string istr = env().intern(pretty_representation);
3205 map[die_offset] = istr;
3206 return istr;
3207 }
3208
3209 return i->second;
3210 }
3211
3212 /// Lookup the artifact that was built to represent a type that has
3213 /// the same pretty representation as the type denoted by a given
3214 /// DIE.
3215 ///
3216 /// Note that the DIE must have previously been associated with the
3217 /// artifact using the functions associate_die_to_decl or
3218 /// associate_die_to_type.
3219 ///
3220 /// Also, note that the scope of the lookup is the current ABI
3221 /// corpus.
3222 ///
3223 /// @param die the DIE to consider.
3224 ///
3225 /// @param where_offset where in the DIE stream we logically are.
3226 ///
3227 /// @return the type artifact found.
3229 lookup_type_artifact_from_die(Dwarf_Die *die) const
3230 {
3231 type_or_decl_base_sptr artifact =
3232 lookup_artifact_from_die(die, /*type_as_die=*/true);
3233 if (function_decl_sptr fn = is_function_decl(artifact))
3234 return fn->get_type();
3235 return artifact;
3236 }
3237
3238 /// Lookup the artifact that was built to represent a type or a
3239 /// declaration that has the same pretty representation as the type
3240 /// denoted by a given DIE.
3241 ///
3242 /// Note that the DIE must have previously been associated with the
3243 /// artifact using the functions associate_die_to_decl or
3244 /// associate_die_to_type.
3245 ///
3246 /// Also, note that the scope of the lookup is the current ABI
3247 /// corpus.
3248 ///
3249 /// @param die the DIE to consider.
3250 ///
3251 /// @param where_offset where in the DIE stream we logically are.
3252 ///
3253 /// @param die_as_type if true, it means the DIE is to be considered
3254 /// as a type.
3255 ///
3256 /// @return the artifact found.
3258 lookup_artifact_from_die(const Dwarf_Die *die, bool die_as_type = false) const
3259 {
3260 Dwarf_Die equiv_die;
3261 if (!get_or_compute_canonical_die(die, equiv_die, /*where=*/0, die_as_type))
3262 return type_or_decl_base_sptr();
3263
3264 const die_artefact_map_type& m =
3265 die_as_type
3266 ? type_die_artefact_maps().get_container(*this, &equiv_die)
3267 : decl_die_artefact_maps().get_container(*this, &equiv_die);
3268
3269 size_t die_offset = dwarf_dieoffset(&equiv_die);
3270 die_artefact_map_type::const_iterator i = m.find(die_offset);
3271
3272 if (i == m.end())
3273 return type_or_decl_base_sptr();
3274 return i->second;
3275 }
3276
3277 /// Lookup the artifact that was built to represent a type or a
3278 /// declaration that has the same pretty representation as the type
3279 /// denoted by the offset of a given DIE.
3280 ///
3281 /// Note that the DIE must have previously been associated with the
3282 /// artifact using either associate_die_to_decl or
3283 /// associate_die_to_type.
3284 ///
3285 /// Also, note that the scope of the lookup is the current ABI
3286 /// corpus.
3287 ///
3288 /// @param die the DIE to consider.
3289 ///
3290 /// @param where_offset where in the DIE stream we logically are.
3291 ///
3292 /// @param die_as_type if true, it means the DIE is to be considered
3293 /// as a type.
3294 ///
3295 /// @return the artifact found.
3297 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3298 die_source source,
3299 bool die_as_type = false) const
3300 {
3301 const die_artefact_map_type& m =
3302 die_as_type
3303 ? type_die_artefact_maps().get_container(source)
3304 : decl_die_artefact_maps().get_container(source);
3305
3306 die_artefact_map_type::const_iterator i = m.find(die_offset);
3307 if (i == m.end())
3308 return type_or_decl_base_sptr();
3309 return i->second;
3310 }
3311
3312 /// Get the language used to generate a given DIE.
3313 ///
3314 /// @param die the DIE to consider.
3315 ///
3316 /// @param lang the resulting language.
3317 ///
3318 /// @return true iff the language of the DIE was found.
3319 bool
3320 get_die_language(const Dwarf_Die *die, translation_unit::language &lang) const
3321 {
3322 Dwarf_Die cu_die;
3323 ABG_ASSERT(dwarf_diecu(const_cast<Dwarf_Die*>(die), &cu_die, 0, 0));
3324
3325 uint64_t l = 0;
3326 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3327 return false;
3328
3329 lang = dwarf_language_to_tu_language(l);
3330 return true;
3331 }
3332
3333 /// Test if a given DIE originates from a program written in the C
3334 /// language.
3335 ///
3336 /// @param die the DIE to consider.
3337 ///
3338 /// @return true iff @p die originates from a program in the C
3339 /// language.
3340 bool
3341 die_is_in_c(const Dwarf_Die *die) const
3342 {
3343 translation_unit::language l = translation_unit::LANG_UNKNOWN;
3344 if (!get_die_language(die, l))
3345 return false;
3346 return is_c_language(l);
3347 }
3348
3349 /// Test if a given DIE originates from a program written in the C++
3350 /// language.
3351 ///
3352 /// @param die the DIE to consider.
3353 ///
3354 /// @return true iff @p die originates from a program in the C++
3355 /// language.
3356 bool
3357 die_is_in_cplus_plus(const Dwarf_Die *die) const
3358 {
3359 translation_unit::language l = translation_unit::LANG_UNKNOWN;
3360 if (!get_die_language(die, l))
3361 return false;
3362 return is_cplus_plus_language(l);
3363 }
3364
3365 /// Test if a given DIE originates from a program written either in
3366 /// C or C++.
3367 ///
3368 /// @param die the DIE to consider.
3369 ///
3370 /// @return true iff @p die originates from a program written either in
3371 /// C or C++.
3372 bool
3373 die_is_in_c_or_cplusplus(const Dwarf_Die *die) const
3374 {
3375 translation_unit::language l = translation_unit::LANG_UNKNOWN;
3376 if (!get_die_language(die, l))
3377 return false;
3378 return (is_cplus_plus_language(l) || is_c_language(l));
3379 }
3380
3381 /// Check if we can assume the One Definition Rule[1] to be relevant
3382 /// for the current translation unit.
3383 ///
3384 /// [1]: https://en.wikipedia.org/wiki/One_Definition_Rule
3385 ///
3386 /// At the moment this returns true if the current translation unit
3387 /// is in C++ language. In that case, it's relevant to assume that
3388 /// we use optimizations based on the ODR.
3389 bool
3390 odr_is_relevant() const
3391 {return odr_is_relevant(cur_transl_unit()->get_language());}
3392
3393 /// Check if we can assume the One Definition Rule[1] to be relevant
3394 /// for a given language.
3395 ///
3396 /// [1]: https://en.wikipedia.org/wiki/One_Definition_Rule
3397 ///
3398 /// At the moment this returns true if the language considered
3399 /// is C++, Java or Ada.
3400 bool
3402 {
3403 return (is_cplus_plus_language(l)
3404 || is_java_language(l)
3405 || is_ada_language(l));
3406 }
3407
3408 /// Check if we can assume the One Definition Rule to be relevant
3409 /// for a given DIE.
3410 ///
3411 /// @param die the DIE to consider.
3412 ///
3413 /// @return true if the ODR is relevant for @p die.
3414 bool
3415 odr_is_relevant(Dwarf_Off die_offset, die_source source) const
3416 {
3417 Dwarf_Die die;
3418 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
3419 die_offset, &die));
3420 return odr_is_relevant(&die);
3421 }
3422
3423 /// Check if we can assume the One Definition Rule to be relevant
3424 /// for a given DIE.
3425 ///
3426 /// @param die the DIE to consider.
3427 ///
3428 /// @return true if the ODR is relevant for @p die.
3429 bool
3430 odr_is_relevant(const Dwarf_Die *die) const
3431 {
3433 if (!get_die_language(die, lang))
3434 return odr_is_relevant();
3435
3436 return odr_is_relevant(lang);
3437 }
3438
3439 /// Getter for the maps set that associates a decl DIE offset to an
3440 /// artifact.
3441 ///
3442 /// @return the maps set that associates a decl DIE offset to an
3443 /// artifact.
3444 die_source_dependant_container_set<die_artefact_map_type>&
3445 decl_die_artefact_maps()
3446 {return decl_die_artefact_maps_;}
3447
3448 /// Getter for the maps set that associates a decl DIE offset to an
3449 /// artifact.
3450 ///
3451 /// @return the maps set that associates a decl DIE offset to an
3452 /// artifact.
3453 const die_source_dependant_container_set<die_artefact_map_type>&
3454 decl_die_artefact_maps() const
3455 {return decl_die_artefact_maps_;}
3456
3457 /// Getter for the maps set that associates a type DIE offset to an
3458 /// artifact.
3459 ///
3460 /// @return the maps set that associates a type DIE offset to an
3461 /// artifact.
3462 die_source_dependant_container_set<die_artefact_map_type>&
3463 type_die_artefact_maps()
3464 {return type_die_artefact_maps_;}
3465
3466 /// Getter for the maps set that associates a type DIE offset to an
3467 /// artifact.
3468 ///
3469 /// @return the maps set that associates a type DIE offset to an
3470 /// artifact.
3471 const die_source_dependant_container_set<die_artefact_map_type>&
3472 type_die_artefact_maps() const
3473 {return type_die_artefact_maps_;}
3474
3475 /// Getter of the maps that associates function type representations
3476 /// to function types, inside a translation unit.
3477 ///
3478 /// @return the maps that associates function type representations
3479 /// to function types, inside a translation unit.
3481 per_tu_repr_to_fn_type_maps()
3482 {return per_tu_repr_to_fn_type_maps_;}
3483
3484 /// Getter of the maps that associates function type representations
3485 /// to function types, inside a translation unit.
3486 ///
3487 /// @return the maps that associates function type representations
3488 /// to function types, inside a translation unit.
3490 per_tu_repr_to_fn_type_maps() const
3491 {return per_tu_repr_to_fn_type_maps_;}
3492
3493 /// Associate the representation of a function type DIE to a given
3494 /// function type, inside the current translation unit.
3495 ///
3496 /// @param die the DIE to associate to the function type, using its
3497 /// representation.
3498 ///
3499 /// @param fn_type the function type to associate to @p die.
3500 void
3501 associate_die_repr_to_fn_type_per_tu(const Dwarf_Die *die,
3502 const function_type_sptr &fn_type)
3503 {
3504 if (!die_is_function_type(die))
3505 return;
3506
3507 interned_string repr =
3508 get_die_pretty_type_representation(die, /*where=*/0);
3509 ABG_ASSERT(!repr.empty());
3510
3511 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3512 }
3513
3514 /// Lookup the function type associated to a given function type
3515 /// DIE, in the current translation unit.
3516 ///
3517 /// @param die the DIE of function type to consider.
3518 ///
3519 /// @return the @ref function_type_sptr associated to @p die, or nil
3520 /// of no function_type is associated to @p die.
3522 lookup_fn_type_from_die_repr_per_tu(const Dwarf_Die *die)
3523 {
3524 if (!die_is_function_type(die))
3525 return function_type_sptr();
3526
3527 interned_string repr = die_name(die).empty() ?
3528 get_die_pretty_type_representation(die, /*where=*/0)
3529 : get_die_pretty_representation(die, /*where=*/0);
3530 ABG_ASSERT(!repr.empty());
3531
3532 istring_fn_type_map_type::const_iterator i =
3533 per_tu_repr_to_fn_type_maps().find(repr);
3534
3535 if (i == per_tu_repr_to_fn_type_maps().end())
3536 return function_type_sptr();
3537
3538 return i->second;
3539 }
3540
3541 /// Set the canonical DIE offset of a given DIE.
3542 ///
3543 /// @param canonical_dies the vector that holds canonical DIEs.
3544 ///
3545 /// @param die_offset the offset of the DIE to set the canonical DIE
3546 /// for.
3547 ///
3548 /// @param canonical_die_offset the canonical DIE offset to
3549 /// associate to @p die_offset.
3550 void
3551 set_canonical_die_offset(offset_offset_map_type &canonical_dies,
3552 Dwarf_Off die_offset,
3553 Dwarf_Off canonical_die_offset) const
3554 {
3555 canonical_dies[die_offset] = canonical_die_offset;}
3556
3557 /// Set the canonical DIE offset of a given DIE.
3558 ///
3559 ///
3560 /// @param die_offset the offset of the DIE to set the canonical DIE
3561 /// for.
3562 ///
3563 /// @param source the source of the DIE denoted by @p die_offset.
3564 ///
3565 /// @param canonical_die_offset the canonical DIE offset to
3566 /// associate to @p die_offset.
3567 ///
3568 /// @param die_as_type if true, it means that @p die_offset has to
3569 /// be considered as a type.
3570 void
3571 set_canonical_die_offset(Dwarf_Off die_offset,
3572 die_source source,
3573 Dwarf_Off canonical_die_offset,
3574 bool die_as_type) const
3575 {
3576 offset_offset_map_type &canonical_dies =
3577 die_as_type
3578 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
3579 get_container(source)
3580 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
3581 get_container(source);
3582
3583 set_canonical_die_offset(canonical_dies,
3584 die_offset,
3585 canonical_die_offset);
3586 }
3587
3588 /// Set the canonical DIE offset of a given DIE.
3589 ///
3590 ///
3591 /// @param die the DIE to set the canonical DIE for.
3592 ///
3593 /// @param canonical_die_offset the canonical DIE offset to
3594 /// associate to @p die_offset.
3595 ///
3596 /// @param die_as_type if true, it means that @p die has to be
3597 /// considered as a type.
3598 void
3599 set_canonical_die_offset(const Dwarf_Die *die,
3600 Dwarf_Off canonical_die_offset,
3601 bool die_as_type) const
3602 {
3603 const die_source source = get_die_source(die);
3604
3605 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3606
3607 set_canonical_die_offset(die_offset, source,
3608 canonical_die_offset,
3609 die_as_type);
3610 }
3611
3612 /// Get the canonical DIE offset of a given DIE.
3613 ///
3614 /// @param canonical_dies the vector that contains canonical DIES.
3615 ///
3616 /// @param die_offset the offset of the DIE to consider.
3617 ///
3618 /// @return the canonical of the DIE denoted by @p die_offset, or
3619 /// zero if no canonical DIE was found.
3620 Dwarf_Off
3621 get_canonical_die_offset(offset_offset_map_type &canonical_dies,
3622 Dwarf_Off die_offset) const
3623 {
3624 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3625 if (it == canonical_dies.end())
3626 return 0;
3627 return it->second;
3628 }
3629
3630 /// Get the canonical DIE offset of a given DIE.
3631 ///
3632 /// @param die_offset the offset of the DIE to consider.
3633 ///
3634 /// @param source the source of the DIE denoted by @p die_offset.
3635 ///
3636 /// @param die_as_type if true, it means that @p is to be considered
3637 /// as a type DIE.
3638 ///
3639 /// @return the canonical of the DIE denoted by @p die_offset, or
3640 /// zero if no canonical DIE was found.
3641 Dwarf_Off
3642 get_canonical_die_offset(Dwarf_Off die_offset,
3643 die_source source,
3644 bool die_as_type) const
3645 {
3646 offset_offset_map_type &canonical_dies =
3647 die_as_type
3648 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
3649 get_container(source)
3650 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
3651 get_container(source);
3652
3653 return get_canonical_die_offset(canonical_dies, die_offset);
3654 }
3655
3656 /// Erase the canonical type of a given DIE.
3657 ///
3658 /// @param die_offset the offset of the DIE to consider.
3659 ///
3660 /// @param source the source of the canonical type.
3661 ///
3662 /// @param die_as_type if true, it means that @p is to be considered
3663 /// as a type DIE.
3664 ///
3665 /// @return the canonical of the DIE denoted by @p die_offset, or
3666 /// zero if no canonical DIE was found and erased..
3667 bool
3668 erase_canonical_die_offset(Dwarf_Off die_offset,
3669 die_source source,
3670 bool die_as_type) const
3671 {
3672 offset_offset_map_type &canonical_dies =
3673 die_as_type
3674 ? const_cast<reader*>(this)->canonical_type_die_offsets_.
3675 get_container(source)
3676 : const_cast<reader*>(this)->canonical_decl_die_offsets_.
3677 get_container(source);
3678
3679 return canonical_dies.erase(die_offset);
3680 }
3681
3682
3683 /// Associate a DIE (representing a type) to the type that it
3684 /// represents.
3685 ///
3686 /// @param die the DIE to consider.
3687 ///
3688 /// @param type the type to associate the DIE to.
3689 ///
3690 /// @param where_offset where in the DIE stream we logically are.
3691 void
3692 associate_die_to_type(const Dwarf_Die *die,
3693 type_base_sptr type,
3694 size_t where)
3695 {
3696 if (!type)
3697 return;
3698
3699 Dwarf_Die equiv_die;
3700 if (!get_or_compute_canonical_die(die, equiv_die, where,
3701 /*die_as_type=*/true))
3702 return;
3703
3705 type_die_artefact_maps().get_container(*this, &equiv_die);
3706
3707 size_t die_offset = dwarf_dieoffset(&equiv_die);
3708 m[die_offset] = type;
3709 }
3710
3711 /// Lookup the type associated to a given DIE.
3712 ///
3713 /// Note that the DIE must have been associated to type by a
3714 /// previous invocation of the function
3715 /// reader::associate_die_to_type().
3716 ///
3717 /// @param die the DIE to consider.
3718 ///
3719 /// @return the type associated to the DIE or NULL if no type is
3720 /// associated to the DIE.
3721 type_base_sptr
3722 lookup_type_from_die(const Dwarf_Die* die) const
3723 {
3724 type_or_decl_base_sptr artifact =
3725 lookup_artifact_from_die(die, /*die_as_type=*/true);
3726 if (function_decl_sptr fn = is_function_decl(artifact))
3727 return fn->get_type();
3728 return is_type(artifact);
3729 }
3730
3731 /// Lookup the type associated to a DIE at a given offset, from a
3732 /// given source.
3733 ///
3734 /// Note that the DIE must have been associated to type by a
3735 /// previous invocation of the function
3736 /// reader::associate_die_to_type().
3737 ///
3738 /// @param die_offset the offset of the DIE to consider.
3739 ///
3740 /// @param source the source of the DIE to consider.
3741 ///
3742 /// @return the type associated to the DIE or NULL if no type is
3743 /// associated to the DIE.
3744 type_base_sptr
3745 lookup_type_from_die_offset(size_t die_offset, die_source source) const
3746 {
3747 type_base_sptr result;
3748 const die_artefact_map_type& m =
3749 type_die_artefact_maps().get_container(source);
3750 die_artefact_map_type::const_iterator i = m.find(die_offset);
3751 if (i != m.end())
3752 {
3753 if (function_decl_sptr fn = is_function_decl(i->second))
3754 return fn->get_type();
3755 result = is_type(i->second);
3756 }
3757
3758 if (!result)
3759 {
3760 // Maybe we are looking for a class type being constructed?
3761 const die_class_or_union_map_type& m = die_wip_classes_map(source);
3762 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3763
3764 if (i != m.end())
3765 result = i->second;
3766 }
3767
3768 if (!result)
3769 {
3770 // Maybe we are looking for a function type being constructed?
3772 die_wip_function_types_map(source);
3773 die_function_type_map_type::const_iterator i = m.find(die_offset);
3774
3775 if (i != m.end())
3776 result = i->second;
3777 }
3778
3779 return result;
3780 }
3781
3782 /// Getter of a map that associates a die that represents a
3783 /// class/struct with the declaration of the class, while the class
3784 /// is being constructed.
3785 ///
3786 /// @param source where the DIE is from.
3787 ///
3788 /// @return the map that associates a DIE to the class that is being
3789 /// built.
3791 die_wip_classes_map(die_source source) const
3792 {return const_cast<reader*>(this)->die_wip_classes_map(source);}
3793
3794 /// Getter of a map that associates a die that represents a
3795 /// class/struct with the declaration of the class, while the class
3796 /// is being constructed.
3797 ///
3798 /// @param source where the DIE comes from.
3799 ///
3800 /// @return the map that associates a DIE to the class that is being
3801 /// built.
3803 die_wip_classes_map(die_source source)
3804 {
3805 switch (source)
3806 {
3807 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3808 break;
3809 case ALT_DEBUG_INFO_DIE_SOURCE:
3810 return alternate_die_wip_classes_map_;
3811 case TYPE_UNIT_DIE_SOURCE:
3812 return type_unit_die_wip_classes_map_;
3813 case NO_DEBUG_INFO_DIE_SOURCE:
3814 case NUMBER_OF_DIE_SOURCES:
3816 }
3817 return die_wip_classes_map_;
3818 }
3819
3820 /// Getter for a map that associates a die (that represents a
3821 /// function type) whith a function type, while the function type is
3822 /// being constructed (WIP == work in progress).
3823 ///
3824 /// @param source where the DIE comes from.n
3825 ///
3826 /// @return the map of wip function types.
3828 die_wip_function_types_map(die_source source) const
3829 {return const_cast<reader*>(this)->die_wip_function_types_map(source);}
3830
3831 /// Getter for a map that associates a die (that represents a
3832 /// function type) whith a function type, while the function type is
3833 /// being constructed (WIP == work in progress).
3834 ///
3835 /// @param source where DIEs of the map come from.
3836 ///
3837 /// @return the map of wip function types.
3839 die_wip_function_types_map(die_source source)
3840 {
3841 switch (source)
3842 {
3843 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3844 break;
3845 case ALT_DEBUG_INFO_DIE_SOURCE:
3846 return alternate_die_wip_function_types_map_;
3847 case TYPE_UNIT_DIE_SOURCE:
3848 return type_unit_die_wip_function_types_map_;
3849 case NO_DEBUG_INFO_DIE_SOURCE:
3850 case NUMBER_OF_DIE_SOURCES:
3852 }
3853 return die_wip_function_types_map_;
3854 }
3855
3856 /// Getter for a map that associates a die with a function decl
3857 /// which has a linkage name but no elf symbol yet.
3858 ///
3859 /// This is to fixup function decls with linkage names, but with no
3860 /// link to their underlying elf symbol. There are some DIEs like
3861 /// that in DWARF sometimes, especially when the compiler optimizes
3862 /// stuff aggressively.
3864 die_function_decl_with_no_symbol_map()
3865 {return die_function_with_no_symbol_map_;}
3866
3867 /// Return true iff a given offset is for the DIE of a class that is
3868 /// being built, but that is not fully built yet. WIP == "work in
3869 /// progress".
3870 ///
3871 /// @param offset the DIE offset to consider.
3872 ///
3873 /// @param source where the DIE of the map come from.
3874 ///
3875 /// @return true iff @p offset is the offset of the DIE of a class
3876 /// that is being currently built.
3877 bool
3878 is_wip_class_die_offset(Dwarf_Off offset, die_source source) const
3879 {
3880 die_class_or_union_map_type::const_iterator i =
3881 die_wip_classes_map(source).find(offset);
3882 return (i != die_wip_classes_map(source).end());
3883 }
3884
3885 /// Return true iff a given offset is for the DIE of a function type
3886 /// that is being built at the moment, but is not fully built yet.
3887 /// WIP == work in progress.
3888 ///
3889 /// @param offset DIE offset to consider.
3890 ///
3891 /// @param source where the DIE comes from.
3892 ///
3893 /// @return true iff @p offset is the offset of the DIE of a
3894 /// function type that is being currently built.
3895 bool
3896 is_wip_function_type_die_offset(Dwarf_Off offset, die_source source) const
3897 {
3898 die_function_type_map_type::const_iterator i =
3899 die_wip_function_types_map(source).find(offset);
3900 return (i != die_wip_function_types_map(source).end());
3901 }
3902
3903 /// Sometimes, a data member die can erroneously have an empty name as
3904 /// a result of a bug of the DWARF emitter.
3905 ///
3906 /// This is what happens in
3907 /// https://sourceware.org/bugzilla/show_bug.cgi?id=29934.
3908 ///
3909 /// In that case, this function constructs an artificial name for that
3910 /// data member. The pattern of the name is as follows:
3911 ///
3912 /// "unnamed-@-<location>".
3913 ///
3914 ///location is either the value of the data member location of the
3915 ///data member if it has one or concatenation of its source location
3916 ///if it has none. If no location can be calculated then the function
3917 ///returns the empty string.
3918 string
3919 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3920 {
3921 string result;
3922 // Let's make sure we are looking at a data member with an empty
3923 // name ...
3924 if (!die
3925 || dwarf_tag(die) != DW_TAG_member
3926 || !die_name(die).empty())
3927 return result;
3928
3929 // ... and yet, it's not an anonymous data member (aka unnamed
3930 // field) as described in
3931 // https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html.
3932 if (die_is_anonymous_data_member(die))
3933 return result;
3934
3935 // If we come this far, it means we are looking at a buggy data
3936 // member with no name. Let's build a name for it so that it can be
3937 // addressed.
3938 int64_t offset_in_bits = 0;
3939 bool has_offset = die_member_offset(*this, die, offset_in_bits);
3940 location loc;
3941 if (!has_offset)
3942 {
3943 loc = die_location(*this, die);
3944 if (!loc)
3945 return result;
3946 }
3947
3948 std::ostringstream o;
3949 o << "unnamed-dm-@-";
3950 if (has_offset)
3951 o << "offset-" << offset_in_bits << "bits";
3952 else
3953 o << "loc-" << loc.expand();
3954
3955 return o.str();
3956 }
3957
3958 /// Getter for the map of declaration-only classes that are to be
3959 /// resolved to their definition classes by the end of the corpus
3960 /// loading.
3961 ///
3962 /// @return a map of string -> vector of classes where the key is
3963 /// the fully qualified name of the class and the value is the
3964 /// vector of declaration-only class.
3966 declaration_only_classes() const
3967 {return decl_only_classes_map_;}
3968
3969 /// Getter for the map of declaration-only classes that are to be
3970 /// resolved to their definition classes by the end of the corpus
3971 /// loading.
3972 ///
3973 /// @return a map of string -> vector of classes where the key is
3974 /// the fully qualified name of the class and the value is the
3975 /// vector of declaration-only class.
3977 declaration_only_classes()
3978 {return decl_only_classes_map_;}
3979
3980 /// If a given class is a declaration-only class then stash it on
3981 /// the side so that at the end of the corpus reading we can resolve
3982 /// it to its definition.
3983 ///
3984 /// @param klass the class to consider.
3985 void
3986 maybe_schedule_declaration_only_class_for_resolution(const class_or_union_sptr& cou)
3987 {
3988 if (cou->get_is_declaration_only()
3989 && cou->get_definition_of_declaration() == 0)
3990 {
3991 string qn = cou->get_qualified_name();
3992 string_classes_or_unions_map::iterator record =
3993 declaration_only_classes().find(qn);
3994 if (record == declaration_only_classes().end())
3995 declaration_only_classes()[qn].push_back(cou);
3996 else
3997 record->second.push_back(cou);
3998 }
3999 }
4000
4001 /// Test if a given declaration-only class has been scheduled for
4002 /// resolution to a defined class.
4003 ///
4004 /// @param klass the class to consider for the test.
4005 ///
4006 /// @return true iff @p klass is a declaration-only class and if
4007 /// it's been scheduled for resolution to a defined class.
4008 bool
4009 is_decl_only_class_scheduled_for_resolution(const class_or_union_sptr& cou)
4010 {
4011 if (cou->get_is_declaration_only())
4012 return (declaration_only_classes().find(cou->get_qualified_name())
4013 != declaration_only_classes().end());
4014
4015 return false;
4016 }
4017
4018 /// Compare two ABI artifacts in a context which canonicalization
4019 /// has not be done yet.
4020 ///
4021 /// @param l the left-hand-side operand of the comparison
4022 ///
4023 /// @param r the right-hand-side operand of the comparison.
4024 ///
4025 /// @return true if @p l equals @p r.
4026 bool
4027 compare_before_canonicalisation(const type_or_decl_base_sptr &l,
4028 const type_or_decl_base_sptr &r)
4029 {
4030 if (!l || !r)
4031 return !!l == !!r;
4032
4033 const environment& e = l->get_environment();
4034 ABG_ASSERT(!e.canonicalization_is_done());
4035
4036 e.priv_->allow_type_comparison_results_caching(true);
4037 bool s0 = e.decl_only_class_equals_definition();
4038 e.decl_only_class_equals_definition(true);
4039 bool equal = l == r;
4040 e.decl_only_class_equals_definition(s0);
4041 e.priv_->clear_type_comparison_results_cache();
4042 e.priv_->allow_type_comparison_results_caching(false);
4043 return equal;
4044 }
4045
4046 /// Walk the declaration-only classes that have been found during
4047 /// the building of the corpus and resolve them to their definitions.
4048 void
4049 resolve_declaration_only_classes()
4050 {
4051 vector<string> resolved_classes;
4052
4053 for (string_classes_or_unions_map::iterator i =
4054 declaration_only_classes().begin();
4055 i != declaration_only_classes().end();
4056 ++i)
4057 {
4058 bool to_resolve = false;
4059 for (classes_or_unions_type::iterator j = i->second.begin();
4060 j != i->second.end();
4061 ++j)
4062 if ((*j)->get_is_declaration_only()
4063 && ((*j)->get_definition_of_declaration() == 0))
4064 to_resolve = true;
4065
4066 if (!to_resolve)
4067 {
4068 resolved_classes.push_back(i->first);
4069 continue;
4070 }
4071
4072 // Now, for each decl-only class that have the current name
4073 // 'i->first', let's try to poke at the fully defined class
4074 // that is defined in the same translation unit as the
4075 // declaration.
4076 //
4077 // If we find one class (defined in the TU of the declaration)
4078 // that defines the declaration, then the declaration can be
4079 // resolved to that class.
4080 //
4081 // If no defining class is found in the TU of the declaration,
4082 // then there are possibly three cases to consider:
4083 //
4084 // 1/ There is exactly one class that defines the
4085 // declaration and that class is defined in another TU. In
4086 // this case, the declaration is resolved to that
4087 // definition.
4088 //
4089 // 2/ There are more than one class that define that
4090 // declaration and none of them is defined in the TU of the
4091 // declaration. If those classes are all different, then
4092 // the declaration is left unresolved.
4093 //
4094 // 3/ No class defines the declaration. In this case, the
4095 // declaration is left unresoved.
4096
4097 // So get the classes that might define the current
4098 // declarations which name is i->first.
4099 const type_base_wptrs_type *classes =
4100 lookup_class_types(i->first, *corpus());
4101 if (!classes)
4102 classes = lookup_union_types(i->first, *corpus());
4103
4104 if (!classes)
4105 continue;
4106
4107 // This is a map that associates the translation unit path to
4108 // the class (that potentially defines the declarations that
4109 // we consider) that are defined in that translation unit. It
4110 // should stay ordered by using the TU path as key to ensure
4111 // stability of the order of classe definitions in ABIXML
4112 // output.
4113 map<string, class_or_union_sptr> per_tu_class_map;
4114 for (type_base_wptrs_type::const_iterator c = classes->begin();
4115 c != classes->end();
4116 ++c)
4117 {
4118 class_or_union_sptr klass = is_class_or_union_type(type_base_sptr(*c));
4119 ABG_ASSERT(klass);
4120
4122 if (klass->get_is_declaration_only())
4123 continue;
4124
4125 string tu_path = klass->get_translation_unit()->get_absolute_path();
4126 if (tu_path.empty())
4127 continue;
4128
4129 // Build a map that associates the translation unit path
4130 // to the class (that potentially defines the declarations
4131 // that we consider) that are defined in that translation unit.
4132 per_tu_class_map[tu_path] = klass;
4133 }
4134
4135 if (!per_tu_class_map.empty())
4136 {
4137 // Walk the declarations to resolve and resolve them
4138 // either to the definitions that are in the same TU as
4139 // the declaration, or to the definition found elsewhere,
4140 // if there is only one such definition.
4141 for (classes_or_unions_type::iterator j = i->second.begin();
4142 j != i->second.end();
4143 ++j)
4144 {
4145 if ((*j)->get_is_declaration_only()
4146 && ((*j)->get_definition_of_declaration() == 0))
4147 {
4148 string tu_path =
4149 (*j)->get_translation_unit()->get_absolute_path();
4150 map<string, class_or_union_sptr>::const_iterator e =
4151 per_tu_class_map.find(tu_path);
4152 if (e != per_tu_class_map.end())
4153 (*j)->set_definition_of_declaration(e->second);
4154 else if (per_tu_class_map.size() == 1)
4155 (*j)->set_definition_of_declaration
4156 (per_tu_class_map.begin()->second);
4157 else
4158 {
4159 // We are in case where there are more than
4160 // one definition for the declaration. Let's
4161 // see if they are all equal. If they are,
4162 // then the declaration resolves to the
4163 // definition. Otherwise, we are in the case
4164 // 3/ described above.
4165 map<string,
4166 class_or_union_sptr>::const_iterator it;
4167 class_or_union_sptr first_class =
4168 per_tu_class_map.begin()->second;
4169 bool all_class_definitions_are_equal = true;
4170 for (it = per_tu_class_map.begin();
4171 it != per_tu_class_map.end();
4172 ++it)
4173 {
4174 if (it == per_tu_class_map.begin())
4175 continue;
4176 else
4177 {
4178 if (!compare_before_canonicalisation(it->second,
4179 first_class))
4180 {
4181 all_class_definitions_are_equal = false;
4182 break;
4183 }
4184 }
4185 }
4186 if (all_class_definitions_are_equal)
4187 (*j)->set_definition_of_declaration(first_class);
4188 }
4189 }
4190 }
4191 resolved_classes.push_back(i->first);
4192 }
4193 }
4194
4195 size_t num_decl_only_classes = declaration_only_classes().size(),
4196 num_resolved = resolved_classes.size();
4197 if (show_stats())
4198 cerr << "resolved " << num_resolved
4199 << " class declarations out of "
4200 << num_decl_only_classes
4201 << "\n";
4202
4203 for (vector<string>::const_iterator i = resolved_classes.begin();
4204 i != resolved_classes.end();
4205 ++i)
4206 declaration_only_classes().erase(*i);
4207
4208 if (show_stats() && !declaration_only_classes().empty())
4209 {
4210 cerr << "Here are the "
4211 << num_decl_only_classes - num_resolved
4212 << " unresolved class declarations:\n";
4213 for (string_classes_or_unions_map::iterator i =
4214 declaration_only_classes().begin();
4215 i != declaration_only_classes().end();
4216 ++i)
4217 cerr << " " << i->first << "\n";
4218 }
4219 }
4220
4221 /// Getter for the map of declaration-only enums that are to be
4222 /// resolved to their definition enums by the end of the corpus
4223 /// loading.
4224 ///
4225 /// @return a map of string -> vector of enums where the key is
4226 /// the fully qualified name of the enum and the value is the
4227 /// vector of declaration-only enum.
4228 const string_enums_map&
4229 declaration_only_enums() const
4230 {return decl_only_enums_map_;}
4231
4232 /// Getter for the map of declaration-only enums that are to be
4233 /// resolved to their definition enums by the end of the corpus
4234 /// loading.
4235 ///
4236 /// @return a map of string -> vector of enums where the key is
4237 /// the fully qualified name of the enum and the value is the
4238 /// vector of declaration-only enum.
4240 declaration_only_enums()
4241 {return decl_only_enums_map_;}
4242
4243 /// If a given enum is a declaration-only enum then stash it on
4244 /// the side so that at the end of the corpus reading we can resolve
4245 /// it to its definition.
4246 ///
4247 /// @param enom the enum to consider.
4248 void
4249 maybe_schedule_declaration_only_enum_for_resolution(enum_type_decl_sptr& enom)
4250 {
4251 if (enom->get_is_declaration_only()
4252 && enom->get_definition_of_declaration() == 0)
4253 {
4254 string qn = enom->get_qualified_name();
4255 string_enums_map::iterator record =
4256 declaration_only_enums().find(qn);
4257 if (record == declaration_only_enums().end())
4258 declaration_only_enums()[qn].push_back(enom);
4259 else
4260 record->second.push_back(enom);
4261 }
4262 }
4263
4264 /// Test if a given declaration-only enum has been scheduled for
4265 /// resolution to a defined enum.
4266 ///
4267 /// @param enom the enum to consider for the test.
4268 ///
4269 /// @return true iff @p enom is a declaration-only enum and if
4270 /// it's been scheduled for resolution to a defined enum.
4271 bool
4272 is_decl_only_enum_scheduled_for_resolution(enum_type_decl_sptr& enom)
4273 {
4274 if (enom->get_is_declaration_only())
4275 return (declaration_only_enums().find(enom->get_qualified_name())
4276 != declaration_only_enums().end());
4277
4278 return false;
4279 }
4280
4281 /// Walk the declaration-only enums that have been found during
4282 /// the building of the corpus and resolve them to their definitions.
4283 ///
4284 /// TODO: Do away with this function by factorizing it with
4285 /// resolve_declaration_only_classes. All declaration-only decls
4286 /// could be handled the same way as declaration-only-ness is a
4287 /// property of abigail::ir::decl_base now.
4288 void
4289 resolve_declaration_only_enums()
4290 {
4291 vector<string> resolved_enums;
4292
4293 for (string_enums_map::iterator i =
4294 declaration_only_enums().begin();
4295 i != declaration_only_enums().end();
4296 ++i)
4297 {
4298 bool to_resolve = false;
4299 for (enums_type::iterator j = i->second.begin();
4300 j != i->second.end();
4301 ++j)
4302 if ((*j)->get_is_declaration_only()
4303 && ((*j)->get_definition_of_declaration() == 0))
4304 to_resolve = true;
4305
4306 if (!to_resolve)
4307 {
4308 resolved_enums.push_back(i->first);
4309 continue;
4310 }
4311
4312 // Now, for each decl-only enum that have the current name
4313 // 'i->first', let's try to poke at the fully defined enum
4314 // that is defined in the same translation unit as the
4315 // declaration.
4316 //
4317 // If we find one enum (defined in the TU of the declaration)
4318 // that defines the declaration, then the declaration can be
4319 // resolved to that enum.
4320 //
4321 // If no defining enum is found in the TU of the declaration,
4322 // then there are possibly three cases to consider:
4323 //
4324 // 1/ There is exactly one enum that defines the
4325 // declaration and that enum is defined in another TU. In
4326 // this case, the declaration is resolved to that
4327 // definition.
4328 //
4329 // 2/ There are more than one enum that define that
4330 // declaration and none of them is defined in the TU of the
4331 // declaration. In this case, the declaration is left
4332 // unresolved.
4333 //
4334 // 3/ No enum defines the declaration. In this case, the
4335 // declaration is left unresoved.
4336
4337 // So get the enums that might define the current
4338 // declarations which name is i->first.
4339 const type_base_wptrs_type *enums =
4340 lookup_enum_types(i->first, *corpus());
4341 if (!enums)
4342 continue;
4343
4344 // This is a map that associates the translation unit path to
4345 // the enum (that potentially defines the declarations that
4346 // we consider) that are defined in that translation unit. It
4347 // should stay ordered by using the TU path as key to ensure
4348 // stability of the order of enum definitions in ABIXML
4349 // output.
4350 map<string, enum_type_decl_sptr> per_tu_enum_map;
4351 for (type_base_wptrs_type::const_iterator c = enums->begin();
4352 c != enums->end();
4353 ++c)
4354 {
4355 enum_type_decl_sptr enom = is_enum_type(type_base_sptr(*c));
4356 ABG_ASSERT(enom);
4357
4359 if (enom->get_is_declaration_only())
4360 continue;
4361
4362 string tu_path = enom->get_translation_unit()->get_absolute_path();
4363 if (tu_path.empty())
4364 continue;
4365
4366 // Build a map that associates the translation unit path
4367 // to the enum (that potentially defines the declarations
4368 // that we consider) that are defined in that translation unit.
4369 per_tu_enum_map[tu_path] = enom;
4370 }
4371
4372 if (!per_tu_enum_map.empty())
4373 {
4374 // Walk the declarations to resolve and resolve them
4375 // either to the definitions that are in the same TU as
4376 // the declaration, or to the definition found elsewhere,
4377 // if there is only one such definition.
4378 for (enums_type::iterator j = i->second.begin();
4379 j != i->second.end();
4380 ++j)
4381 {
4382 if ((*j)->get_is_declaration_only()
4383 && ((*j)->get_definition_of_declaration() == 0))
4384 {
4385 string tu_path =
4386 (*j)->get_translation_unit()->get_absolute_path();
4387 map<string, enum_type_decl_sptr>::const_iterator e =
4388 per_tu_enum_map.find(tu_path);
4389 if (e != per_tu_enum_map.end())
4390 (*j)->set_definition_of_declaration(e->second);
4391 else if (per_tu_enum_map.size() == 1)
4392 (*j)->set_definition_of_declaration
4393 (per_tu_enum_map.begin()->second);
4394 else
4395 {
4396 // We are in case where there are more than
4397 // one definition for the declaration. Let's
4398 // see if they are all equal. If they are,
4399 // then the declaration resolves to the
4400 // definition. Otherwise, we are in the case
4401 // 3/ described above.
4402 map<string,
4403 enum_type_decl_sptr>::const_iterator it;
4404 enum_type_decl_sptr first_enum =
4405 per_tu_enum_map.begin()->second;
4406 bool all_enum_definitions_are_equal = true;
4407 for (it = per_tu_enum_map.begin();
4408 it != per_tu_enum_map.end();
4409 ++it)
4410 {
4411 if (it == per_tu_enum_map.begin())
4412 continue;
4413 else
4414 {
4415 if (!compare_before_canonicalisation(it->second,
4416 first_enum))
4417 {
4418 all_enum_definitions_are_equal = false;
4419 break;
4420 }
4421 }
4422 }
4423 if (all_enum_definitions_are_equal)
4424 (*j)->set_definition_of_declaration(first_enum);
4425 }
4426 }
4427 }
4428 resolved_enums.push_back(i->first);
4429 }
4430 }
4431
4432 size_t num_decl_only_enums = declaration_only_enums().size(),
4433 num_resolved = resolved_enums.size();
4434 if (show_stats())
4435 cerr << "resolved " << num_resolved
4436 << " enum declarations out of "
4437 << num_decl_only_enums
4438 << "\n";
4439
4440 for (vector<string>::const_iterator i = resolved_enums.begin();
4441 i != resolved_enums.end();
4442 ++i)
4443 declaration_only_enums().erase(*i);
4444
4445 if (show_stats() && !declaration_only_enums().empty())
4446 {
4447 cerr << "Here are the "
4448 << num_decl_only_enums - num_resolved
4449 << " unresolved enum declarations:\n";
4450 for (string_enums_map::iterator i = declaration_only_enums().begin();
4451 i != declaration_only_enums().end();
4452 ++i)
4453 cerr << " " << i->first << "\n";
4454 }
4455 }
4456
4457 /// Test if a symbol belongs to a function of the current ABI
4458 /// corpus.
4459 ///
4460 /// This is a sub-routine of fixup_functions_with_no_symbols.
4461 ///
4462 /// @param fn the function symbol to consider.
4463 ///
4464 /// @returnt true if @p fn belongs to a function of the current ABI
4465 /// corpus.
4466 bool
4467 symbol_already_belongs_to_a_function(elf_symbol_sptr& fn)
4468 {
4469 corpus_sptr corp = corpus();
4470 if (!corp)
4471 return false;
4472
4473 string id = fn->get_id_string();
4474
4475 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(id);
4476 if (!fns)
4477 return false;
4478
4479 for (auto f : *fns)
4480 if (f->get_symbol())
4481 return true;
4482
4483 return false;
4484 }
4485
4486 /// Some functions described by DWARF may have their linkage name
4487 /// set, but no link to their actual underlying elf symbol. When
4488 /// these are virtual member functions, comparing the enclosing type
4489 /// against another one which has its underlying symbol properly set
4490 /// might lead to spurious type changes.
4491 ///
4492 /// If the corpus contains a symbol with the same name as the
4493 /// linkage name of the function, then set up the link between the
4494 /// function and its underlying symbol.
4495 ///
4496 /// Note that for the moment, only virtual member functions are
4497 /// fixed up like this. This is because they really are the only
4498 /// fuctions of functions that can affect types (in spurious ways).
4499 void
4500 fixup_functions_with_no_symbols()
4501 {
4502 corpus_sptr corp = corpus();
4503 if (!corp)
4504 return;
4505
4506 die_function_decl_map_type &fns_with_no_symbol =
4507 die_function_decl_with_no_symbol_map();
4508
4509 if (do_log())
4510 cerr << fns_with_no_symbol.size()
4511 << " functions to fixup, potentially\n";
4512
4513 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4514 i != fns_with_no_symbol.end();
4515 ++i)
4516 if (elf_symbol_sptr sym =
4517 corp->lookup_function_symbol(i->second->get_linkage_name()))
4518 {
4519 // So i->second is a virtual member function that was
4520 // previously scheduled to be set a function symbol.
4521 //
4522 // But if it appears that it now has a symbol already set,
4523 // then do not set a symbol to it again.
4524 //
4525 // Or if it appears that another virtual member function
4526 // from the current ABI Corpus, with the same linkage
4527 // (mangled) name has already been set a symbol, then do not
4528 // set a symbol to this function either. Otherwise, there
4529 // will be two virtual member functions with the same symbol
4530 // in the class and that leads to spurious hard-to-debug
4531 // change reports later down the road.
4532 if (i->second->get_symbol()
4533 || symbol_already_belongs_to_a_function(sym))
4534 continue;
4535
4536 ABG_ASSERT(is_member_function(i->second));
4538 i->second->set_symbol(sym);
4539 // The function_decl now has an associated (public) ELF symbol so
4540 // it ought to be advertised as being public.
4541 i->second->set_is_in_public_symbol_table(true);
4542 // Add the function to the set of exported decls of the
4543 // current corpus.
4544 maybe_add_fn_to_exported_decls(i->second.get());
4545 if (do_log())
4546 cerr << "fixed up '"
4547 << i->second->get_pretty_representation()
4548 << "' with symbol '"
4549 << sym->get_id_string()
4550 << "'\n";
4551 }
4552
4553 fns_with_no_symbol.clear();
4554 }
4555
4556 /// Return a reference to the vector containing the types created
4557 /// during the binary analysis but that are not tied to a given
4558 /// DWARF DIE.
4559 ///
4560 /// @return reference to the vector containing the types created
4561 /// during the binary analysis but that are not tied to a given
4562 /// DWARF DIE.
4563 const vector<type_base_sptr>&
4564 types_to_canonicalize() const
4565 {return types_to_canonicalize_;}
4566
4567 /// Clear the containers holding types to canonicalize.
4568 void
4569 clear_types_to_canonicalize()
4570 {
4571 types_to_canonicalize_.clear();
4572 }
4573
4574 /// Types that were created but not tied to a particular DIE, must
4575 /// be scheduled for late canonicalization using this method.
4576 ///
4577 /// @param t the type to schedule for late canonicalization.
4578 void
4579 schedule_type_for_late_canonicalization(const type_base_sptr &t)
4580 {
4581 types_to_canonicalize_.push_back(t);
4582 }
4583
4584 /// Canonicalize types which DIE offsets are stored in vectors on
4585 /// the side. This is a sub-routine of
4586 /// reader::perform_late_type_canonicalizing().
4587 ///
4588 /// @param source where the DIE of the types to canonicalize are
4589 /// from.
4590 void
4591 canonicalize_types_scheduled()
4592 {
4593 tools_utils::timer cn_timer;
4594 if (do_log())
4595 {
4596 cerr << "going to canonicalize types";
4597 corpus_sptr c = corpus();
4598 if (c)
4599 cerr << " of corpus " << corpus()->get_path();
4600 cn_timer.start();
4601 }
4602
4603 if (!types_to_canonicalize().empty())
4604 canonicalize_types(types_to_canonicalize().begin(),
4605 types_to_canonicalize().end(),
4606 [](const vector<type_base_sptr>::const_iterator& i)
4607 {return *i;});
4608
4609 if (do_log())
4610 {
4611 cn_timer.stop();
4612 cerr << "finished canonicalizing types";
4613 corpus_sptr c = corpus();
4614 if (c)
4615 cerr << " of corpus " << corpus()->get_path();
4616 cerr << ": (" << cn_timer << ")\n";
4617 }
4618 }
4619
4620 /// Compute the number of canonicalized and missed types in the late
4621 /// canonicalization phase.
4622 ///
4623 /// @param source where the DIEs of the canonicalized types are
4624 /// from.
4625 ///
4626 /// @param canonicalized the number of types that got canonicalized
4627 /// is added to the value already present in this parameter.
4628 ///
4629 /// @param missed the number of types scheduled for late
4630 /// canonicalization and which couldn't be canonicalized (for a
4631 /// reason) is added to the value already present in this parameter.
4632 void
4633 add_late_canonicalized_types_stats(size_t& canonicalized,
4634 size_t& missed) const
4635 {
4636 for (auto t : types_to_canonicalize())
4637 {
4638 if (t->get_canonical_type())
4639 ++canonicalized;
4640 else
4641 ++missed;
4642 }
4643 }
4644
4645 // Look at the types that need to be canonicalized after the
4646 // translation unit has been constructed and canonicalize them.
4647 void
4648 perform_late_type_canonicalizing()
4649 {
4650 canonicalize_types_scheduled();
4651
4652 if (show_stats())
4653 {
4654 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4655 add_late_canonicalized_types_stats(num_canonicalized,
4656 num_missed);
4657 total = num_canonicalized + num_missed;
4658 cerr << "binary: "
4659 << elf_path()
4660 << "\n";
4661 cerr << " # late canonicalized types: "
4662 << num_canonicalized;
4663 if (total)
4664 cerr << " (" << num_canonicalized * 100 / total << "%)";
4665 cerr << "\n"
4666 << " # missed canonicalization opportunities: "
4667 << num_missed;
4668 if (total)
4669 cerr << " (" << num_missed * 100 / total << "%)";
4670 cerr << "\n";
4671 }
4672
4673 }
4674
4675 const die_tu_map_type&
4676 die_tu_map() const
4677 {return die_tu_map_;}
4678
4680 die_tu_map()
4681 {return die_tu_map_;}
4682
4683 /// Getter for the map that associates a translation unit DIE to the
4684 /// vector of imported unit points that it contains.
4685 ///
4686 /// @param source where the DIEs are from.
4687 ///
4688 /// @return the map.
4690 tu_die_imported_unit_points_map(die_source source) const
4691 {return const_cast<reader*>(this)->tu_die_imported_unit_points_map(source);}
4692
4693 /// Getter for the map that associates a translation unit DIE to the
4694 /// vector of imported unit points that it contains.
4695 ///
4696 /// @param source where the DIEs are from.
4697 ///
4698 /// @return the map.
4700 tu_die_imported_unit_points_map(die_source source)
4701 {
4702 switch (source)
4703 {
4704 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4705 break;
4706 case ALT_DEBUG_INFO_DIE_SOURCE:
4707 return alt_tu_die_imported_unit_points_map_;
4708 case TYPE_UNIT_DIE_SOURCE:
4709 return type_units_tu_die_imported_unit_points_map_;
4710 case NO_DEBUG_INFO_DIE_SOURCE:
4711 case NUMBER_OF_DIE_SOURCES:
4712 // We cannot reach this point.
4714 }
4715 return tu_die_imported_unit_points_map_;
4716 }
4717
4718 /// Reset the current corpus being constructed.
4719 ///
4720 /// This actually deletes the current corpus being constructed.
4721 void
4722 reset_corpus()
4723 {corpus().reset();}
4724
4725 /// Get the map that associates each DIE to its parent DIE. This is
4726 /// for DIEs coming from the main debug info sections.
4727 ///
4728 /// @param source where the DIEs in the map come from.
4729 ///
4730 /// @return the DIE -> parent map.
4732 die_parent_map(die_source source) const
4733 {return const_cast<reader*>(this)->die_parent_map(source);}
4734
4735 /// Get the map that associates each DIE to its parent DIE. This is
4736 /// for DIEs coming from the main debug info sections.
4737 ///
4738 /// @param source where the DIEs in the map come from.
4739 ///
4740 /// @return the DIE -> parent map.
4742 die_parent_map(die_source source)
4743 {
4744 switch (source)
4745 {
4746 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4747 break;
4748 case ALT_DEBUG_INFO_DIE_SOURCE:
4749 return alternate_die_parent_map_;
4750 case TYPE_UNIT_DIE_SOURCE:
4751 return type_section_die_parent_map();
4752 case NO_DEBUG_INFO_DIE_SOURCE:
4753 case NUMBER_OF_DIE_SOURCES:
4755 }
4756 return primary_die_parent_map_;
4757 }
4758
4760 type_section_die_parent_map() const
4761 {return type_section_die_parent_map_;}
4762
4764 type_section_die_parent_map()
4765 {return type_section_die_parent_map_;}
4766
4767 /// Getter of the current translation unit.
4768 ///
4769 /// @return the current translation unit being constructed.
4771 cur_transl_unit() const
4772 {return cur_tu_;}
4773
4774 /// Getter of the current translation unit.
4775 ///
4776 /// @return the current translation unit being constructed.
4778 cur_transl_unit()
4779 {return cur_tu_;}
4780
4781 /// Setter of the current translation unit.
4782 ///
4783 /// @param tu the current translation unit being constructed.
4784 void
4785 cur_transl_unit(translation_unit_sptr tu)
4786 {
4787 if (tu)
4788 cur_tu_ = tu;
4789 }
4790
4791 /// Return the global scope of the current translation unit.
4792 ///
4793 /// @return the global scope of the current translation unit.
4794 const scope_decl_sptr&
4795 global_scope() const
4796 {return cur_transl_unit()->get_global_scope();}
4797
4798 /// Return a scope that is nil.
4799 ///
4800 /// @return a scope that is nil.
4801 const scope_decl_sptr&
4802 nil_scope() const
4803 {return nil_scope_;}
4804
4805 const scope_stack_type&
4806 scope_stack() const
4807 {return scope_stack_;}
4808
4810 scope_stack()
4811 {return scope_stack_;}
4812
4813 scope_decl*
4814 current_scope()
4815 {
4816 if (scope_stack().empty())
4817 {
4818 if (cur_transl_unit())
4819 scope_stack().push(cur_transl_unit()->get_global_scope().get());
4820 }
4821 return scope_stack().top();
4822 }
4823
4824 list<var_decl_sptr>&
4825 var_decls_to_re_add_to_tree()
4826 {return var_decls_to_add_;}
4827
4828 /// Test if a DIE represents a decl (function or variable) that has
4829 /// a symbol that is exported, whatever that means. This is
4830 /// supposed to work for Linux Kernel binaries as well.
4831 ///
4832 /// This is useful to limit the amount of DIEs taken into account to
4833 /// the strict limit of what an ABI actually means. Limiting the
4834 /// volume of DIEs analyzed this way is an important optimization to
4835 /// keep big binaries "manageable" by libabigail.
4836 ///
4837 /// @param DIE the die to consider.
4838 bool
4839 is_decl_die_with_exported_symbol(const Dwarf_Die *die)
4840 {
4841 if (!die || !die_is_decl(die))
4842 return false;
4843
4844 bool result = false, address_found = false, symbol_is_exported = false;;
4845 Dwarf_Addr decl_symbol_address = 0;
4846
4847 if (die_is_variable_decl(die))
4848 {
4849 if ((address_found = get_variable_address(die, decl_symbol_address)))
4850 symbol_is_exported =
4851 !!variable_symbol_is_exported(decl_symbol_address);
4852 }
4853 else if (die_is_function_decl(die))
4854 {
4855 if ((address_found = get_function_address(die, decl_symbol_address)))
4856 symbol_is_exported =
4857 !!function_symbol_is_exported(decl_symbol_address);
4858 }
4859
4860 if (address_found)
4861 result = symbol_is_exported;
4862
4863 return result;
4864 }
4865
4866 /// This is a sub-routine of maybe_adjust_fn_sym_address and
4867 /// maybe_adjust_var_sym_address.
4868 ///
4869 /// Given an address that we got by looking at some debug
4870 /// information (e.g, a symbol's address referred to by a DWARF
4871 /// TAG), If the ELF file we are interested in is a shared library
4872 /// or an executable, then adjust the address to be coherent with
4873 /// where the executable (or shared library) is loaded. That way,
4874 /// the address can be used to look for symbols in the executable or
4875 /// shared library.
4876 ///
4877 /// @return the adjusted address, or the same address as @p addr if
4878 /// it didn't need any adjustment.
4879 Dwarf_Addr
4880 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr) const
4881 {
4882 if (addr == 0)
4883 return addr;
4884
4885 GElf_Ehdr eh_mem;
4886 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4887
4888 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4889 {
4890 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4891 ABG_ASSERT(get_binary_load_address(dwarf_elf_handle(),
4892 dwarf_elf_load_address));
4894 elf_load_address));
4895 if (dwarf_is_splitted()
4896 && (dwarf_elf_load_address != elf_load_address))
4897 // This means that in theory the DWARF and the executable are
4898 // not loaded at the same address. And addr is meaningful
4899 // only in the context of the DWARF.
4900 //
4901 // So let's transform addr into an offset relative to where
4902 // the DWARF is loaded, and let's add that relative offset
4903 // to the load address of the executable. That way, addr
4904 // becomes meaningful in the context of the executable and
4905 // can thus be used to compare against the address of
4906 // symbols of the executable, for instance.
4907 addr = addr - dwarf_elf_load_address + elf_load_address;
4908 }
4909
4910 return addr;
4911 }
4912
4913 /// For a relocatable (*.o) elf file, this function expects an
4914 /// absolute address, representing a function symbol. It then
4915 /// extracts the address of the .text section from the symbol
4916 /// absolute address to get the relative address of the function
4917 /// from the beginning of the .text section.
4918 ///
4919 /// For executable or shared library, this function expects an
4920 /// address of a function symbol that was retrieved by looking at a
4921 /// DWARF "file". The function thus adjusts the address to make it
4922 /// be meaningful in the context of the ELF file.
4923 ///
4924 /// In both cases, the address can then be compared against the
4925 /// st_value field of a function symbol from the ELF file.
4926 ///
4927 /// @param addr an adress for a function symbol that was retrieved
4928 /// from a DWARF file.
4929 ///
4930 /// @return the (possibly) adjusted address, or just @p addr if no
4931 /// adjustment took place.
4932 Dwarf_Addr
4933 maybe_adjust_fn_sym_address(Dwarf_Addr addr) const
4934 {
4935 if (addr == 0)
4936 return addr;
4937
4938 Elf* elf = elf_handle();
4939 GElf_Ehdr eh_mem;
4940 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4941
4942 if (elf_header->e_type == ET_REL)
4943 // We are looking at a relocatable file. In this case, we don't
4944 // do anything because:
4945 //
4946 // 1/ the addresses from DWARF are absolute (relative to the
4947 // beginning of the relocatable file)
4948 //
4949 // 2/ The ELF symbol addresses that we store in our lookup
4950 // tables are translated from section-related to absolute as
4951 // well. So we don't have anything to do at this point for
4952 // ET_REL files.
4953 ;
4954 else
4955 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4956
4957 return addr;
4958 }
4959
4960 /// For a relocatable (*.o) elf file, this function expects an
4961 /// absolute address, representing a global variable symbol. It
4962 /// then extracts the address of the {.data,.data1,.rodata,.bss}
4963 /// section from the symbol absolute address to get the relative
4964 /// address of the variable from the beginning of the data section.
4965 ///
4966 /// For executable or shared library, this function expects an
4967 /// address of a variable symbol that was retrieved by looking at a
4968 /// DWARF "file". The function thus adjusts the address to make it
4969 /// be meaningful in the context of the ELF file.
4970 ///
4971 /// In both cases, the address can then be compared against the
4972 /// st_value field of a function symbol from the ELF file.
4973 ///
4974 /// @param addr an address for a global variable symbol that was
4975 /// retrieved from a DWARF file.
4976 ///
4977 /// @return the (possibly) adjusted address, or just @p addr if no
4978 /// adjustment took place.
4979 Dwarf_Addr
4980 maybe_adjust_var_sym_address(Dwarf_Addr addr) const
4981 {
4982 Elf* elf = elf_handle();
4983 GElf_Ehdr eh_mem;
4984 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4985
4986 if (elf_header->e_type == ET_REL)
4987 // We are looking at a relocatable file. In this case, we don't
4988 // do anything because:
4989 //
4990 // 1/ the addresses from DWARF are absolute (relative to the
4991 // beginning of the relocatable file)
4992 //
4993 // 2/ The ELF symbol addresses that we store in our lookup
4994 // tables are translated from section-related to absolute as
4995 // well. So we don't have anything to do at this point for
4996 // ET_REL files.
4997 ;
4998 else
4999 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5000
5001 return addr;
5002 }
5003
5004 /// Get the first exported function address in the set of addresses
5005 /// referred to by the DW_AT_ranges attribute of a given DIE.
5006 ///
5007 /// @param die the DIE we are considering.
5008 ///
5009 /// @param address output parameter. This is set to the first
5010 /// address found in the sequence pointed to by the DW_AT_ranges
5011 /// attribute found on the DIE @p die, iff the function returns
5012 /// true. Otherwise, no value is set into this output parameter.
5013 ///
5014 /// @return true iff the DIE @p die does have a DW_AT_ranges
5015 /// attribute and an address of an exported function was found in
5016 /// its sequence value.
5017 bool
5018 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5019 Dwarf_Addr& address) const
5020 {
5021 Dwarf_Addr base;
5022 Dwarf_Addr end_addr;
5023 ptrdiff_t offset = 0;
5024
5025 do
5026 {
5027 Dwarf_Addr addr = 0, fn_addr = 0;
5028 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5029 {
5030 fn_addr = maybe_adjust_fn_sym_address(addr);
5031 if (function_symbol_is_exported(fn_addr))
5032 {
5033 address = fn_addr;
5034 return true;
5035 }
5036 }
5037 } while (offset > 0);
5038 return false;
5039 }
5040
5041 /// Get the address of the function.
5042 ///
5043 /// The address of the function is considered to be the value of the
5044 /// DW_AT_low_pc attribute, possibly adjusted (in relocatable files
5045 /// only) to not point to an absolute address anymore, but rather to
5046 /// the address of the function inside the .text segment.
5047 ///
5048 /// @param function_die the die of the function to consider.
5049 ///
5050 /// @param address the resulting address iff the function returns
5051 /// true.
5052 ///
5053 /// @return true if the function address was found.
5054 bool
5055 get_function_address(const Dwarf_Die* function_die, Dwarf_Addr& address) const
5056 {
5057 if (!die_address_attribute(const_cast<Dwarf_Die*>(function_die),
5058 DW_AT_low_pc, address))
5059 // So no DW_AT_low_pc was found. Let's see if the function DIE
5060 // has got a DW_AT_ranges attribute instead. If it does, the
5061 // first address of the set of addresses represented by the
5062 // value of that DW_AT_ranges represents the function (symbol)
5063 // address we are looking for.
5064 if (!get_first_exported_fn_address_from_DW_AT_ranges
5065 (const_cast<Dwarf_Die*>(function_die),
5066 address))
5067 return false;
5068
5069 address = maybe_adjust_fn_sym_address(address);
5070 return true;
5071 }
5072
5073 /// Get the address of the global variable.
5074 ///
5075 /// The address of the global variable is considered to be the value
5076 /// of the DW_AT_location attribute, possibly adjusted (in
5077 /// relocatable files only) to not point to an absolute address
5078 /// anymore, but rather to the address of the global variable inside
5079 /// the data segment.
5080 ///
5081 /// @param variable_die the die of the function to consider.
5082 ///
5083 /// @param address the resulting address iff this function returns
5084 /// true.
5085 ///
5086 /// @return true if the variable address was found.
5087 bool
5088 get_variable_address(const Dwarf_Die* variable_die,
5089 Dwarf_Addr& address) const
5090 {
5091 bool is_tls_address = false;
5092 if (!die_location_address(const_cast<Dwarf_Die*>(variable_die),
5093 address, is_tls_address))
5094 return false;
5095 if (!is_tls_address)
5096 address = maybe_adjust_var_sym_address(address);
5097 return true;
5098 }
5099
5100 /// Getter of the exported decls builder object.
5101 ///
5102 /// @return the exported decls builder.
5103 corpus::exported_decls_builder*
5104 exported_decls_builder()
5105 {return corpus()->get_exported_decls_builder().get();}
5106
5107 /// Getter of the "load_all_types" flag. This flag tells if all the
5108 /// types (including those not reachable by public declarations) are
5109 /// to be read and represented in the final ABI corpus.
5110 ///
5111 /// @return the load_all_types flag.
5112 bool
5113 load_all_types() const
5114 {return options().load_all_types;}
5115
5116 /// Setter of the "load_all_types" flag. This flag tells if all the
5117 /// types (including those not reachable by public declarations) are
5118 /// to be read and represented in the final ABI corpus.
5119 ///
5120 /// @param f the new load_all_types flag.
5121 void
5122 load_all_types(bool f)
5123 {options().load_all_types = f;}
5124
5125 bool
5126 load_in_linux_kernel_mode() const
5127 {return options().load_in_linux_kernel_mode;}
5128
5129 void
5130 load_in_linux_kernel_mode(bool f)
5131 {options().load_in_linux_kernel_mode = f;}
5132
5133 /// Test if it's allowed to assume that the DWARF debug info has
5134 /// been factorized (for instance, with the DWZ tool) so that if two
5135 /// type DIEs originating from the .gnu_debugaltlink section have
5136 /// different offsets, they represent different types.
5137 ///
5138 /// @return true iff we can assume that the DWARF debug info has
5139 /// been factorized.
5140 bool
5141 leverage_dwarf_factorization() const
5142 {
5143 if (!leverage_dwarf_factorization_.has_value())
5144 {
5145 if (options().leverage_dwarf_factorization
5146 && elf_helpers::find_section_by_name(elf_handle(),
5147 ".gnu_debugaltlink"))
5148 leverage_dwarf_factorization_ = true;
5149 else
5150 leverage_dwarf_factorization_ = false;
5151 }
5152 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5153
5154 return *leverage_dwarf_factorization_;
5155 }
5156 /// Getter of the "show_stats" flag.
5157 ///
5158 /// This flag tells if we should emit statistics about various
5159 /// internal stuff.
5160 ///
5161 /// @return the value of the flag.
5162 bool
5163 show_stats() const
5164 {return options().show_stats;}
5165
5166 /// Setter of the "show_stats" flag.
5167 ///
5168 /// This flag tells if we should emit statistics about various
5169 /// internal stuff.
5170 ///
5171 /// @param f the value of the flag.
5172 void
5173 show_stats(bool f)
5174 {options().show_stats = f;}
5175
5176 /// Getter of the "do_log" flag.
5177 ///
5178 /// This flag tells if we should log about various internal
5179 /// details.
5180 ///
5181 /// return the "do_log" flag.
5182 bool
5183 do_log() const
5184 {return options().do_log;}
5185
5186 /// Setter of the "do_log" flag.
5187 ///
5188 /// This flag tells if we should log about various internal details.
5189 ///
5190 /// @param f the new value of the flag.
5191 void
5192 do_log(bool f)
5193 {options().do_log = f;}
5194
5195 /// Walk the DIEs under a given die and for each child, populate the
5196 /// die -> parent map to record the child -> parent relationship
5197 /// that
5198 /// exists between the child and the given die.
5199 ///
5200 /// The function also builds the vector of places where units are
5201 /// imported.
5202 ///
5203 /// This is done recursively as for each child DIE, this function
5204 /// walks its children as well.
5205 ///
5206 /// @param die the DIE whose children to walk recursively.
5207 ///
5208 /// @param source where the DIE @p die comes from.
5209 ///
5210 /// @param imported_units a vector containing all the offsets of the
5211 /// points where unit have been imported, under @p die.
5212 void
5213 build_die_parent_relations_under(Dwarf_Die* die,
5214 die_source source,
5215 imported_unit_points_type & imported_units)
5216 {
5217 if (!die)
5218 return;
5219
5220 offset_offset_map_type& parent_of = die_parent_map(source);
5221
5222 Dwarf_Die child;
5223 if (dwarf_child(die, &child) != 0)
5224 return;
5225
5226 do
5227 {
5228 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5229 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5230 {
5231 Dwarf_Die imported_unit;
5232 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5233 // If the imported_unit has a sub-tree, let's record
5234 // this point at which the sub-tree is imported into
5235 // the current debug info.
5236 //
5237 // Otherwise, if the imported_unit has no sub-tree,
5238 // there is no point in recording where a non-existent
5239 // sub-tree is being imported.
5240 //
5241 // Note that the imported_unit_points_type type below
5242 // expects the imported_unit to have a sub-tree.
5243 && die_has_children(&imported_unit))
5244 {
5245 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5246 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5247 imported_units.push_back
5248 (imported_unit_point(dwarf_dieoffset(&child),
5249 imported_unit,
5250 imported_unit_die_source));
5251 }
5252 }
5253 build_die_parent_relations_under(&child, source, imported_units);
5254 }
5255 while (dwarf_siblingof(&child, &child) == 0);
5256
5257 }
5258
5259 /// Determine if we do have to build a DIE -> parent map, depending
5260 /// on a given language.
5261 ///
5262 /// Some languages like C++, Ada etc, do have the concept of
5263 /// namespace and yet, the DIE data structure doesn't provide us
5264 /// with a way to get the parent namespace of a given DIE. So for
5265 /// those languages, we need to build a DIE -> parent map so that we
5266 /// can get the namespace DIE (or more generally the scope DIE) of a given
5267 /// DIE as we need it.
5268 ///
5269 /// But then some more basic languages like C or assembly don't have
5270 /// that need.
5271 ///
5272 /// This function, depending on the language, tells us if we need to
5273 /// build the DIE -> parent map or not.
5274 ///
5275 /// @param lang the language to consider.
5276 ///
5277 /// @return true iff we need to build the DIE -> parent map for this
5278 /// language.
5279 bool
5280 do_we_build_die_parent_maps(translation_unit::language lang)
5281 {
5282 if (is_c_language(lang))
5283 return false;
5284
5285 switch (lang)
5286 {
5287 case translation_unit::LANG_UNKNOWN:
5288#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5289 case translation_unit::LANG_Mips_Assembler:
5290#endif
5291 return false;
5292 default:
5293 break;
5294 }
5295 return true;
5296 }
5297
5298 /// Walk all the DIEs accessible in the debug info (and in the
5299 /// alternate debug info as well) and build maps representing the
5300 /// relationship DIE -> parent. That is, make it so that we can get
5301 /// the parent for a given DIE.
5302 ///
5303 /// Note that the goal of this map is to be able to get the parent
5304 /// of a given DIE. This is to mainly to handle namespaces. For instance,
5305 /// when we get a DIE of a type, and we want to build an internal
5306 /// representation for it, we need to get its fully qualified name.
5307 /// For that, we need to know what is the parent DIE of that type
5308 /// DIE, so that we can know what the namespace of that type is.
5309 ///
5310 /// Note that as the C language doesn't have namespaces (all types
5311 /// are defined in the same global namespace), this function doesn't
5312 /// build the DIE -> parent map if the current translation unit
5313 /// comes from C. This saves time on big C ELF files with a lot of
5314 /// DIEs.
5315 void
5316 build_die_parent_maps()
5317 {
5318 bool we_do_have_to_build_die_parent_map = false;
5319 uint8_t address_size = 0;
5320 size_t header_size = 0;
5321 // Get the DIE of the current translation unit, look at it to get
5322 // its language. If that language is in C, then all types are in
5323 // the global namespace so we don't need to build the DIE ->
5324 // parent map. So we dont build it in that case.
5325 for (Dwarf_Off offset = 0, next_offset = 0;
5326 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5327 offset, &next_offset, &header_size,
5328 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5329 offset = next_offset)
5330 {
5331 Dwarf_Off die_offset = offset + header_size;
5332 Dwarf_Die cu;
5333 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5334 die_offset, &cu))
5335 continue;
5336
5337 uint64_t l = 0;
5338 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5339 translation_unit::language lang = dwarf_language_to_tu_language(l);
5340 if (do_we_build_die_parent_maps(lang))
5341 we_do_have_to_build_die_parent_map = true;
5342 }
5343
5344 if (!we_do_have_to_build_die_parent_map)
5345 return;
5346
5347 // Build the DIE -> parent relation for DIEs coming from the
5348 // .debug_info section in the alternate debug info file.
5349 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5350 for (Dwarf_Off offset = 0, next_offset = 0;
5351 (dwarf_next_unit(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5352 offset, &next_offset, &header_size,
5353 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5354 offset = next_offset)
5355 {
5356 Dwarf_Off die_offset = offset + header_size;
5357 Dwarf_Die cu;
5358 if (!dwarf_offdie(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5359 die_offset, &cu))
5360 continue;
5361 cur_tu_die(&cu);
5362
5363 imported_unit_points_type& imported_units =
5364 tu_die_imported_unit_points_map(source)[die_offset] =
5366 build_die_parent_relations_under(&cu, source, imported_units);
5367 }
5368
5369 // Build the DIE -> parent relation for DIEs coming from the
5370 // .debug_info section of the main debug info file.
5371 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5372 address_size = 0;
5373 header_size = 0;
5374 for (Dwarf_Off offset = 0, next_offset = 0;
5375 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5376 offset, &next_offset, &header_size,
5377 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5378 offset = next_offset)
5379 {
5380 Dwarf_Off die_offset = offset + header_size;
5381 Dwarf_Die cu;
5382 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5383 die_offset, &cu))
5384 continue;
5385 cur_tu_die(&cu);
5386 imported_unit_points_type& imported_units =
5387 tu_die_imported_unit_points_map(source)[die_offset] =
5389 build_die_parent_relations_under(&cu, source, imported_units);
5390 }
5391
5392 // Build the DIE -> parent relation for DIEs coming from the
5393 // .debug_types section.
5394 source = TYPE_UNIT_DIE_SOURCE;
5395 address_size = 0;
5396 header_size = 0;
5397 uint64_t type_signature = 0;
5398 Dwarf_Off type_offset;
5399 for (Dwarf_Off offset = 0, next_offset = 0;
5400 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5401 offset, &next_offset, &header_size,
5402 NULL, NULL, &address_size, NULL,
5403 &type_signature, &type_offset) == 0);
5404 offset = next_offset)
5405 {
5406 Dwarf_Off die_offset = offset + header_size;
5407 Dwarf_Die cu;
5408
5409 if (!dwarf_offdie_types(const_cast<Dwarf*>(dwarf_debug_info()),
5410 die_offset, &cu))
5411 continue;
5412 cur_tu_die(&cu);
5413 imported_unit_points_type& imported_units =
5414 tu_die_imported_unit_points_map(source)[die_offset] =
5416 build_die_parent_relations_under(&cu, source, imported_units);
5417 }
5418 }
5419};// end class reader.
5420
5421/// The type of the aggregates being compared during a DIE comparison.
5422///
5423/// This encapsulates the stack of aggregates being compared at any
5424/// single point.
5425///
5426/// This is useful to detect "comparison cycles" and thus avoid the
5427/// resulting infinite loops.
5428///
5429/// This is also useful for implementing a very important optimization
5430/// that takes place during the canonicalization
5431struct offset_pairs_stack_type
5432{
5433 // The DWARF DWARF reader that is useful for so many things.
5434 const reader& rdr_;
5435 // The set of types that are being compared. This is to speed up
5436 // searches.
5438 // The stack of types that are being compared. The top of the
5439 // stack is the back of the vector.
5441 // A map that associates a redundant type pair to the vector of
5442 // types that depends on it.
5443 offset_pair_vect_map_type redundant_types_;
5444 // A map that associates a dependant type to the vector of redundant
5445 // types it depends on.
5446 offset_pair_vect_map_type dependant_types_;
5447
5448 offset_pairs_stack_type(const reader& rdr)
5449 : rdr_ (rdr)
5450 {}
5451
5452 /// Add a pair of types being compared to the stack of aggregates
5453 /// being compared.
5454 ///
5455 /// @param p the pair of offsets of the type DIEs to consider.
5456 void
5457 add(const offset_pair_type& p)
5458 {
5459 set_.insert(p);
5460 vect_.push_back(p);
5461 }
5462
5463 /// Erase a pair of types being compared from the stack of
5464 /// aggregates being compared.
5465 ///
5466 /// @param p the pair of offsets of the type DIEs to consider.
5467 ///
5468 /// @return true iff @p was found and erased from the stack.
5469 bool
5470 erase(const offset_pair_type& p)
5471 {
5472 if (set_.erase(p))
5473 {
5474 offset_pair_vector_type::iterator i;
5475
5476 for (i = vect_.begin();i < vect_.end(); ++i)
5477 if (*i == p)
5478 break;
5479
5480 if (i != vect_.end())
5481 vect_.erase(i);
5482
5483 return true;
5484 }
5485
5486 return false;
5487 }
5488
5489 /// Test if a pair of type DIEs is part of the stack of type DIEs
5490 /// being compared.
5491 ///
5492 /// @param p the pair of offsets of the type DIEs to consider.
5493 ///
5494 /// @return true iff @p was found in the stack of types being
5495 /// compared.
5496 bool
5497 contains(const offset_pair_type &p) const
5498 {
5499 if (set_.find(p) == set_.end())
5500 return false;
5501 return true;
5502 }
5503
5504 /// Get the set of comparison pair that depends on a given
5505 /// comparison pair.
5506 ///
5507 /// A comparison pair T{t1,t2} depends on a comparison pair P{p1,p2}
5508 /// if p1 is a subtype of t1 and p2 is a subtype of t2. In other
5509 /// words, the pair T appears in the comparison stack BEFORE the
5510 /// pair P.
5511 ///
5512 /// So, this function returns the vector of comparison pairs that
5513 /// appear in the comparison stack AFTER a given comparison pair.
5514 ///
5515 /// @param p the comparison pair to consider.
5516 ///
5517 /// @param pairs out parameter. This is filled with the comparison
5518 /// pairs that depend on @p, iff the function returns true.
5519 ///
5520 /// @return true iff comparison pairs depending on @p have been
5521 /// found and collected in @pairs.
5522 bool
5523 get_pairs_that_depend_on(const offset_pair_type& p,
5524 offset_pair_vector_type& pairs) const
5525 {
5526 bool result = false;
5527 if (!contains(p))
5528 return result;
5529
5530 // First, get an iterator on the position of 'p'.
5531 offset_pair_vector_type::const_iterator i;
5532 for (i = vect_.begin(); i != vect_.end(); ++i)
5533 if (*i == p)
5534 break;
5535
5536 if (i == vect_.end())
5537 return result;
5538
5539 // Then, harvest all the comparison pairs that come after the
5540 // position of 'p'.
5541 for (++i; i != vect_.end(); ++i)
5542 {
5543 pairs.push_back(*i);
5544 result = true;
5545 }
5546
5547 return result;
5548 }
5549
5550 /// Record the fact that a set of comparison pairs depends on a
5551 /// given comparison pair.
5552 ///
5553 /// Set a map that associates each dependant comparison pair to the
5554 /// pair it depends on.
5555 ///
5556 /// @param p the comparison pair that the set depends on.
5557 ///
5558 /// @param dependant_types the set of types that depends on @p.
5559 void
5560 record_dependant_types(const offset_pair_type& p,
5561 const offset_pair_vector_type& dependant_types)
5562 {
5563 for (auto type_pair : dependant_types)
5564 dependant_types_[type_pair].push_back(p);
5565 }
5566
5567 /// Record a comparison pair as being redundant.
5568 ///
5569 ///
5570 /// @param p the comparison pair to record as redundant.
5571 void
5572 record_redundant_type_die_pair(const offset_pair_type& p)
5573 {
5574 offset_pair_vector_type dependant_types;
5575 get_pairs_that_depend_on(p, dependant_types);
5576
5577 // First, record the relationship "p -> [pairs that depend on p]".
5578 auto it = redundant_types_.find(p);
5579 if (it == redundant_types_.end())
5580 {
5581 auto entry = std::make_pair(p, dependant_types);
5582 redundant_types_.insert(entry);
5583 }
5584 else
5585 it->second.insert(it->second.end(),
5586 dependant_types.begin(),
5587 dependant_types.end());
5588
5589 // For each dependant type pair, record the association:
5590 // dependant_pair --> [vect of redundant types]
5591 record_dependant_types(p, dependant_types);
5592 }
5593
5594 /// Test if a given pair has been detected as redundant.
5595 ///
5596 /// @param p the pair of DIEs to consider.
5597 ///
5598 /// @return iff @p is redundant.
5599 bool
5600 is_redundant(const offset_pair_type& p)
5601 {
5602 auto i = redundant_types_.find(p);
5603 if (i != redundant_types_.end())
5604 return true;
5605 return false;
5606 }
5607
5608 /// Test if a given pair is dependant on at least a redundant type.
5609 ///
5610 /// @param p the pair to consider.
5611 ///
5612 /// @return true iff @p depends on a redundant type.
5613 bool
5614 depends_on_redundant_types(const offset_pair_type& p)
5615 {
5616 auto i = dependant_types_.find(p);
5617 if (i == dependant_types_.end())
5618 return false;
5619 return true;
5620 }
5621
5622 /// Remove a redundant pair from the system.
5623 ///
5624 /// This needs updating the system to also remove the dependant
5625 /// types that depend on the redundant pair (if they depend only on
5626 /// that redundant pair).
5627 ///
5628 /// @param p the pair to consider.
5629 ///
5630 /// @param erase_canonical_die_offset if true then erase the cached
5631 /// comparison results for the redundant pair and its dependant
5632 /// types.
5633 void
5634 erase_redundant_type_pair_entry(const offset_pair_type& p,
5635 bool erase_cached_results = false)
5636 {
5637 // First, update the dependant types that depend on the redundant
5638 // type pair
5639 auto redundant_type = redundant_types_.find(p);
5640 if (redundant_type != redundant_types_.end())
5641 {
5642 for (auto dependant_type : redundant_type->second)
5643 {
5644 // Each dependant_type depends on the redundant type 'p',
5645 // among others.
5646 auto dependant_types_it = dependant_types_.find(dependant_type);
5647 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5648 // Erase the redundant type 'p' from the redundant types
5649 // that dependant_type depends on.
5650 {
5651 auto i = dependant_types_it->second.begin();
5652 for (; i!= dependant_types_it->second.end();++i)
5653 if (*i == p)
5654 break;
5655 if (i != dependant_types_it->second.end())
5656 dependant_types_it->second.erase(i);
5657 }
5658 // If the dependant type itself doesn't depend on ANY
5659 // redundant type anymore, then remove the depend type
5660 // from the map of the dependant types.
5661 if (dependant_types_it->second.empty())
5662 {
5663 if (erase_cached_results)
5664 rdr_.die_comparison_results_.erase(dependant_type);
5665 dependant_types_.erase(dependant_types_it);
5666 }
5667 }
5668 }
5669 if (erase_cached_results)
5670 rdr_.die_comparison_results_.erase(p);
5671 redundant_types_.erase(p);
5672 }
5673
5674 /// If a comparison pair has been detected as redundant, stop
5675 /// tracking it as well as its dependant pairs. That will
5676 /// essentially make it impossible to reset/cancel the canonical
5677 /// propagated types for those depdant pairs, but will also save
5678 /// ressources.
5679 ///
5680 /// @param p the comparison pair to consider.
5681 void
5682 confirm_canonical_propagated_type(const offset_pair_type& p)
5683 {erase_redundant_type_pair_entry(p, /*erase_cached_results=*/true);}
5684
5685 /// Walk the types that depend on a comparison pair and cancel their
5686 /// canonical-propagate-type, that means remove their canonical
5687 /// types and mark them as not being canonically-propagated. Also,
5688 /// erase their cached comparison results that was likely set to
5689 /// COMPARISON_RESULT_UNKNOWN.
5690 ///
5691 /// @param p the pair to consider.
5692 void
5693 cancel_canonical_propagated_type(const offset_pair_type& p)
5694 {
5695 offset_pair_set_type dependant_types;
5696 get_dependant_types(p, dependant_types, /*transitive_closure=*/true);
5697 for (auto dependant_type : dependant_types)
5698 {
5699 // If this dependant type was canonical-type-propagated then
5700 // erase that canonical type.
5701 if (rdr_.propagated_types_.find(dependant_type)
5702 != rdr_.propagated_types_.end())
5703 {
5704 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5705 dependant_type.first.source_,
5706 /*die_as_type=*/true);
5707 rdr_.propagated_types_.erase(dependant_type);
5708 rdr_.cancelled_propagation_count_++;
5709 }
5710 // Update the cached result. We know the comparison result
5711 // must now be different.
5712 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5713 if (comp_result_it != rdr_.die_comparison_results_.end())
5714 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5715 }
5716
5717 // Update the cached result of the root type to cancel too.
5718 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5719 if (comp_result_it != rdr_.die_comparison_results_.end())
5720 {
5721 // At this point, the result of p is either
5722 // COMPARISON_RESULT_UNKNOWN (if we cache comparison
5723 // results of that kind) or COMPARISON_RESULT_DIFFERENT.
5724 // Make sure it's the cached result is now
5725 // COMPARISON_RESULT_DIFFERENT.
5726 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5727 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5728 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5729 }
5730
5731 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5732 {
5733 rdr_.erase_canonical_die_offset(p.first.offset_,
5734 p.first.source_,
5735 /*die_as_type=*/true);
5736 rdr_.propagated_types_.erase(p);
5737 rdr_.cancelled_propagation_count_++;
5738 }
5739 }
5740
5741 /// Get the set of comparison pairs that depend on a given pair.
5742 ///
5743 /// @param p the pair to consider.
5744 ///
5745 /// @param result this is set to the pairs that depend on @p, iff
5746 /// the function returned true.
5747 ///
5748 /// @param transitive_closure if set to true, the transitive closure
5749 /// of the @result is set to it.
5750 ///
5751 /// @return true iff @result could be filled with the dependant
5752 /// types.
5753 bool
5754 get_dependant_types(const offset_pair_type& p,
5755 offset_pair_set_type& result,
5756 bool transitive_closure = false)
5757 {
5758 auto i = redundant_types_.find(p);
5759 if (i != redundant_types_.end())
5760 {
5761 for (auto dependant_type : i->second)
5762 if (result.find(dependant_type) == result.end())
5763 {
5764 result.insert(dependant_type);
5765 if (transitive_closure)
5766 get_dependant_types(p, result, /*transitive_closure=*/true);
5767 }
5768 return true;
5769 }
5770 return false;
5771 }
5772}; // end struct offset_pairs_stack_type
5773
5775build_ir_node_from_die(reader& rdr,
5776 Dwarf_Die* die,
5777 scope_decl* scope,
5778 bool called_from_public_decl,
5779 size_t where_offset,
5780 bool is_declaration_only = true,
5781 bool is_required_decl_spec = false);
5782
5784build_ir_node_from_die(reader& rdr,
5785 Dwarf_Die* die,
5786 bool called_from_public_decl,
5787 size_t where_offset);
5788
5789static class_decl_sptr
5790add_or_update_class_type(reader& rdr,
5791 Dwarf_Die* die,
5792 scope_decl* scope,
5793 bool is_struct,
5794 class_decl_sptr klass,
5795 bool called_from_public_decl,
5796 size_t where_offset,
5797 bool is_declaration_only);
5798
5799static union_decl_sptr
5800add_or_update_union_type(reader& rdr,
5801 Dwarf_Die* die,
5802 scope_decl* scope,
5803 union_decl_sptr union_type,
5804 bool called_from_public_decl,
5805 size_t where_offset,
5806 bool is_declaration_only);
5807
5808static decl_base_sptr
5809build_ir_node_for_void_type(reader& rdr);
5810
5811static decl_base_sptr
5812build_ir_node_for_variadic_parameter_type(reader &rdr);
5813
5814static function_decl_sptr
5815build_function_decl(reader& rdr,
5816 Dwarf_Die* die,
5817 size_t where_offset,
5819
5820static bool
5821function_is_suppressed(const reader& rdr,
5822 const scope_decl* scope,
5823 Dwarf_Die *function_die,
5824 bool is_declaration_only);
5825
5826static function_decl_sptr
5827build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5828 scope_decl *scope,
5829 Dwarf_Die *die,
5830 size_t where_offset,
5831 bool is_declaration_only,
5833
5834static var_decl_sptr
5835build_var_decl(reader& rdr,
5836 Dwarf_Die *die,
5837 size_t where_offset,
5838 var_decl_sptr result = var_decl_sptr());
5839
5840static var_decl_sptr
5841build_or_get_var_decl_if_not_suppressed(reader& rdr,
5842 scope_decl *scope,
5843 Dwarf_Die *die,
5844 size_t where_offset,
5846 bool is_required_decl_spec = false);
5847static bool
5848variable_is_suppressed(const reader& rdr,
5849 const scope_decl* scope,
5850 Dwarf_Die *variable_die,
5851 bool is_required_decl_spec = false);
5852
5853static void
5854finish_member_function_reading(Dwarf_Die* die,
5855 const function_decl_sptr& f,
5856 const class_or_union_sptr klass,
5857 reader& rdr);
5858
5859/// Test if a given DIE is anonymous
5860///
5861/// @param die the DIE to consider.
5862///
5863/// @return true iff @p die is anonymous.
5864static bool
5865die_is_anonymous(const Dwarf_Die* die)
5866{
5867 Dwarf_Attribute attr;
5868 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), DW_AT_name, &attr))
5869 return true;
5870 return false;
5871}
5872
5873/// Test if a DIE is an anonymous data member, aka, "unnamed field".
5874///
5875/// Unnamed fields are specified at
5876/// https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html.
5877///
5878/// @param die the DIE to consider.
5879///
5880/// @return true iff @p die is an anonymous data member.
5881static bool
5882die_is_anonymous_data_member(const Dwarf_Die* die)
5883{
5884 if (!die
5885 || dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_member
5886 || !die_name(die).empty())
5887 return false;
5888
5889 Dwarf_Die type_die;
5890 if (!die_die_attribute(die, DW_AT_type, type_die))
5891 return false;
5892
5893 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5894 && dwarf_tag(&type_die) != DW_TAG_union_type)
5895 return false;
5896
5897 return true;
5898}
5899
5900/// Get the value of an attribute that is supposed to be a string, or
5901/// an empty string if the attribute could not be found.
5902///
5903/// @param die the DIE to get the attribute value from.
5904///
5905/// @param attr_name the attribute name. Must come from dwarf.h and
5906/// be an enumerator representing an attribute like, e.g, DW_AT_name.
5907///
5908/// @return the string representing the value of the attribute, or an
5909/// empty string if no string attribute could be found.
5910static string
5911die_string_attribute(const Dwarf_Die* die, unsigned attr_name)
5912{
5913 if (!die)
5914 return "";
5915
5916 Dwarf_Attribute attr;
5917 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
5918 return "";
5919
5920 const char* str = dwarf_formstring(&attr);
5921 return str ? str : "";
5922}
5923
5924/// Get the value of an attribute that is supposed to be a string, or
5925/// an empty string if the attribute could not be found.
5926///
5927/// @param die the DIE to get the attribute value from.
5928///
5929/// @param attr_name the attribute name. Must come from dwarf.h and
5930/// be an enumerator representing an attribute like, e.g, DW_AT_name.
5931///
5932/// @return the char* representing the value of the attribute, or an
5933/// empty string if no string attribute could be found.
5934static const char*
5935die_char_str_attribute(const Dwarf_Die* die, unsigned attr_name)
5936{
5937 if (!die)
5938 return nullptr;
5939
5940 Dwarf_Attribute attr;
5941 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
5942 return nullptr;
5943
5944 const char* str = dwarf_formstring(&attr);
5945 return str;
5946}
5947
5948/// Get the value of an attribute that is supposed to be an unsigned
5949/// constant.
5950///
5951/// @param die the DIE to read the information from.
5952///
5953/// @param attr_name the DW_AT_* name of the attribute. Must come
5954/// from dwarf.h and be an enumerator representing an attribute like,
5955/// e.g, DW_AT_decl_line.
5956///
5957///@param cst the output parameter that is set to the value of the
5958/// attribute @p attr_name. This parameter is set iff the function
5959/// return true.
5960///
5961/// @return true if there was an attribute of the name @p attr_name
5962/// and with a value that is a constant, false otherwise.
5963static bool
5964die_unsigned_constant_attribute(const Dwarf_Die* die,
5965 unsigned attr_name,
5966 uint64_t& cst)
5967{
5968 if (!die)
5969 return false;
5970
5971 Dwarf_Attribute attr;
5972 Dwarf_Word result = 0;
5973 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
5974 || dwarf_formudata(&attr, &result))
5975 return false;
5976
5977 cst = result;
5978 return true;
5979}
5980
5981/// Read a signed constant value from a given attribute.
5982///
5983/// The signed constant expected must be of constant form.
5984///
5985/// @param die the DIE to get the attribute from.
5986///
5987/// @param attr_name the attribute name.
5988///
5989/// @param cst the resulting signed constant read.
5990///
5991/// @return true iff a signed constant attribute of the name @p
5992/// attr_name was found on the DIE @p die.
5993static bool
5994die_signed_constant_attribute(const Dwarf_Die *die,
5995 unsigned attr_name,
5996 int64_t& cst)
5997{
5998 if (!die)
5999 return false;
6000
6001 Dwarf_Attribute attr;
6002 Dwarf_Sword result = 0;
6003 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6004 || dwarf_formsdata(&attr, &result))
6005 return false;
6006
6007 cst = result;
6008 return true;
6009}
6010
6011/// Read the value of a constant attribute that is either signed or
6012/// unsigned into a array_type_def::subrange_type::bound_value value.
6013///
6014/// The bound_value instance will capture the actual signedness of the
6015/// read attribute.
6016///
6017/// @param die the DIE from which to read the value of the attribute.
6018///
6019/// @param attr_name the attribute name to consider.
6020///
6021/// @param is_signed true if the attribute value has to read as
6022/// signed.
6023///
6024/// @param value the resulting value read from attribute @p attr_name
6025/// on DIE @p die.
6026///
6027/// @return true iff DIE @p die has an attribute named @p attr_name
6028/// with a constant value.
6029static bool
6030die_constant_attribute(const Dwarf_Die *die,
6031 unsigned attr_name,
6032 bool is_signed,
6033 array_type_def::subrange_type::bound_value &value)
6034{
6035 if (!is_signed)
6036 {
6037 uint64_t l = 0;
6038 if (!die_unsigned_constant_attribute(die, attr_name, l))
6039 return false;
6040 value.set_unsigned(l);
6041 }
6042 else
6043 {
6044 int64_t l = 0;
6045 if (!die_signed_constant_attribute(die, attr_name, l))
6046 return false;
6047 value.set_signed(l);
6048 }
6049 return true;
6050}
6051
6052/// Test if a given DWARF form is DW_FORM_strx{1,4}.
6053///
6054/// Unfortunaly, the DW_FORM_strx{1,4} are enumerators of an untagged
6055/// enum in dwarf.h so we have to use an unsigned int for the form,
6056/// grrr.
6057///
6058/// @param form the form to consider.
6059///
6060/// @return true iff @p form is DW_FORM_strx{1,4}.
6061static bool
6062form_is_DW_FORM_strx(unsigned form)
6063{
6064 if (form)
6065 {
6066#if defined HAVE_DW_FORM_strx1 \
6067 && defined HAVE_DW_FORM_strx2 \
6068 && defined HAVE_DW_FORM_strx3 \
6069 && defined HAVE_DW_FORM_strx4
6070 if (form == DW_FORM_strx1
6071 || form == DW_FORM_strx2
6072 || form == DW_FORM_strx3
6073 ||form == DW_FORM_strx4)
6074 return true;
6075#endif
6076 }
6077 return false;
6078}
6079
6080/// Test if a given DWARF form is DW_FORM_line_strp.
6081///
6082/// Unfortunaly, the DW_FORM_line_strp is an enumerator of an untagged
6083/// enum in dwarf.h so we have to use an unsigned int for the form,
6084/// grrr.
6085///
6086/// @param form the form to consider.
6087///
6088/// @return true iff @p form is DW_FORM_line_strp.
6089static bool
6090form_is_DW_FORM_line_strp(unsigned form)
6091{
6092 if (form)
6093 {
6094#if defined HAVE_DW_FORM_line_strp
6095 if (form == DW_FORM_line_strp)
6096 return true;
6097#endif
6098 }
6099 return false;
6100}
6101
6102/// Get the value of a DIE attribute; that value is meant to be a
6103/// flag.
6104///
6105/// @param die the DIE to get the attribute from.
6106///
6107/// @param attr_name the DW_AT_* name of the attribute. Must come
6108/// from dwarf.h and be an enumerator representing an attribute like,
6109/// e.g, DW_AT_external.
6110///
6111/// @param flag the output parameter to store the flag value into.
6112/// This is set iff the function returns true.
6113///
6114/// @param recursively if true, the function looks through the
6115/// possible DW_AT_specification and DW_AT_abstract_origin attribute
6116/// all the way down to the initial DIE that is cloned and look on
6117/// that DIE to see if it has the @p attr_name attribute.
6118///
6119/// @return true if the DIE has a flag attribute named @p attr_name,
6120/// false otherwise.
6121static bool
6122die_flag_attribute(const Dwarf_Die* die,
6123 unsigned attr_name,
6124 bool& flag,
6125 bool recursively = true)
6126{
6127 Dwarf_Attribute attr;
6128 if (recursively
6129 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6130 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6131 return false;
6132
6133 bool f = false;
6134 if (dwarf_formflag(&attr, &f))
6135 return false;
6136
6137 flag = f;
6138 return true;
6139}
6140
6141/// Get the mangled name from a given DIE.
6142///
6143/// @param die the DIE to read the mangled name from.
6144///
6145/// @return the mangled name if it's present in the DIE, or just an
6146/// empty string if it's not.
6147static string
6148die_linkage_name(const Dwarf_Die* die)
6149{
6150 if (!die)
6151 return "";
6152
6153 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6154 if (linkage_name.empty())
6155 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6156 return linkage_name;
6157}
6158
6159/// Get the file path that is the value of the DW_AT_decl_file
6160/// attribute on a given DIE, if the DIE is a decl DIE having that
6161/// attribute.
6162///
6163/// @param die the DIE to consider.
6164///
6165/// @return a string containing the file path that is the logical
6166/// value of the DW_AT_decl_file attribute. If the DIE @p die
6167/// doesn't have a DW_AT_decl_file attribute, then the return value is
6168/// just an empty string.
6169static string
6170die_decl_file_attribute(const Dwarf_Die* die)
6171{
6172 if (!die)
6173 return "";
6174
6175 const char* str = dwarf_decl_file(const_cast<Dwarf_Die*>(die));
6176
6177 return str ? str : "";
6178}
6179
6180/// Get the value of an attribute which value is supposed to be a
6181/// reference to a DIE.
6182///
6183/// @param die the DIE to read the value from.
6184///
6185/// @param attr_name the DW_AT_* attribute name to read.
6186///
6187/// @param result the DIE resulting from reading the attribute value.
6188/// This is set iff the function returns true.
6189///
6190/// @param recursively if true, the function looks through the
6191/// possible DW_AT_specification and DW_AT_abstract_origin attribute
6192/// all the way down to the initial DIE that is cloned and look on
6193/// that DIE to see if it has the @p attr_name attribute.
6194///
6195/// @return true if the DIE @p die contains an attribute named @p
6196/// attr_name that is a DIE reference, false otherwise.
6197static bool
6198die_die_attribute(const Dwarf_Die* die,
6199 unsigned attr_name,
6200 Dwarf_Die& result,
6201 bool recursively)
6202{
6203 Dwarf_Attribute attr;
6204 if (recursively
6205 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6206 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6207 return false;
6208
6209 return dwarf_formref_die(&attr, &result);
6210}
6211
6212/// Test if a subrange DIE indirectly references another subrange DIE
6213/// through a given attribute.
6214///
6215/// A DW_TAG_subrange_type DIE can have its DW_AT_{lower,upper}_bound
6216/// attribute be a reference to either a data member or a variable
6217/// which type is itself a DW_TAG_subrange_type. This latter subrange
6218/// DIE is said to be "indirectly referenced" by the former subrange
6219/// DIE. In that case, the DW_AT_{lower,upper}_bound of the latter is
6220/// the value we want for the DW_AT_upper_bound of the former.
6221///
6222/// This function tests if the former subrange DIE does indirectly
6223/// reference another subrange DIE through a given attribute (not
6224/// necessarily DW_AT_upper_bound).
6225///
6226/// @param die the DIE to consider. Note that It must be a
6227/// DW_TAG_subrange_type.
6228///
6229/// @param attr_name the name of the attribute to look through for the
6230/// indirectly referenced subrange DIE.
6231///
6232/// @param referenced_subrange if the function returns true, then the
6233/// argument of this parameter is set to the indirectly referenced
6234/// DW_TAG_subrange_type DIE.
6235///
6236/// @return true iff @p DIE indirectly references a subrange DIE
6237/// through the attribute @p attr_name.
6238static bool
6239subrange_die_indirectly_references_subrange_die(const Dwarf_Die *die,
6240 unsigned attr_name,
6241 Dwarf_Die& referenced_subrange)
6242{
6243 bool result = false;
6244
6245 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6246 return result;
6247
6248 Dwarf_Die referenced_die;
6249 if (die_die_attribute(die, attr_name, referenced_die))
6250 {
6251 unsigned tag = dwarf_tag(&referenced_die);
6252 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6253 {
6254 Dwarf_Die type_die;
6255 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6256 {
6257 tag = dwarf_tag(&type_die);
6258 if (tag == DW_TAG_subrange_type)
6259 {
6260 memcpy(&referenced_subrange, &type_die, sizeof(type_die));
6261 result = true;
6262 }
6263 }
6264 }
6265 }
6266 return result;
6267}
6268
6269/// Return the bound value of subrange die by looking at an indirectly
6270/// referenced subrange DIE.
6271///
6272/// A DW_TAG_subrange_type DIE can have its DW_AT_{lower,upper}_bound
6273/// attribute be a reference to either a data member or a variable
6274/// which type is itself a DW_TAG_subrange_type. This latter subrange
6275/// DIE is said to be "indirectly referenced" by the former subrange
6276/// DIE. In that case, the DW_AT_{lower,upper}_bound of the latter is
6277/// the value we want for the DW_AT_{lower,upper}_bound of the former.
6278///
6279/// This function gets the DW_AT_{lower,upper}_bound value of a
6280/// subrange type by looking at the DW_AT_{lower,upper}_bound value of
6281/// the indirectly referenced subrange type, if it exists.
6282///
6283/// @param die the subrange DIE to consider.
6284///
6285/// @param attr_name the name of the attribute to consider, typically,
6286/// DW_AT_{lower,upper}_bound.
6287///
6288/// @param v the found value, iff this function returned true.
6289///
6290/// @param is_signed, this is set to true if @p v is signed. This
6291/// parameter is set at all only if the function returns true.
6292///
6293/// @return true iff the DW_AT_{lower,upper}_bound was found on the
6294/// indirectly referenced subrange type.
6295static bool
6296subrange_die_indirect_bound_value(const Dwarf_Die *die,
6297 unsigned attr_name,
6298 array_type_def::subrange_type::bound_value& v,
6299 bool& is_signed)
6300{
6301 bool result = false;
6302
6303 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6304 return result;
6305
6306 Dwarf_Die subrange_die;
6307 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6308 subrange_die))
6309 {
6310 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6311 result = true;
6312 }
6313 return result;
6314}
6315
6316/// Read and return an addresss class attribute from a given DIE.
6317///
6318/// @param die the DIE to consider.
6319///
6320/// @param attr_name the name of the address class attribute to read
6321/// the value from.
6322///
6323/// @param the resulting address.
6324///
6325/// @return true iff the attribute could be read, was of the expected
6326/// address class and could thus be translated into the @p result.
6327static bool
6328die_address_attribute(Dwarf_Die* die, unsigned attr_name, Dwarf_Addr& result)
6329{
6330 Dwarf_Attribute attr;
6331 if (!dwarf_attr_integrate(die, attr_name, &attr))
6332 return false;
6333 return dwarf_formaddr(&attr, &result) == 0;
6334}
6335
6336/// Returns the source location associated with a decl DIE.
6337///
6338/// @param rdr the @ref reader to use.
6339///
6340/// @param die the DIE the read the source location from.
6341///
6342/// @return the location associated with @p die.
6343static location
6344die_location(const reader& rdr, const Dwarf_Die* die)
6345{
6346 if (!die)
6347 return location();
6348
6349 string file = die_decl_file_attribute(die);
6350 uint64_t line = 0;
6351 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6352
6353 if (!file.empty() && line != 0)
6354 {
6355 translation_unit_sptr tu = rdr.cur_transl_unit();
6356 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6357 return l;
6358 }
6359 return location();
6360}
6361
6362/// Return a copy of the name of a DIE.
6363///
6364/// @param die the DIE to consider.
6365///
6366/// @return a copy of the name of the DIE.
6367static string
6368die_name(const Dwarf_Die* die)
6369{
6370 string name = die_string_attribute(die, DW_AT_name);
6371 return name;
6372}
6373
6374/// Return the location, the name and the mangled name of a given DIE.
6375///
6376/// @param rdr the DWARF reader to use.
6377///
6378/// @param die the DIE to read location and names from.
6379///
6380/// @param loc the location output parameter to set.
6381///
6382/// @param name the name output parameter to set.
6383///
6384/// @param linkage_name the linkage_name output parameter to set.
6385static void
6386die_loc_and_name(const reader& rdr,
6387 Dwarf_Die* die,
6388 location& loc,
6389 string& name,
6390 string& linkage_name)
6391{
6392 loc = die_location(rdr, die);
6393 name = die_name(die);
6394 linkage_name = die_linkage_name(die);
6395}
6396
6397/// Get the size of a (type) DIE as the value for the parameter
6398/// DW_AT_byte_size or DW_AT_bit_size.
6399///
6400/// @param die the DIE to read the information from.
6401///
6402/// @param size the resulting size in bits. This is set iff the
6403/// function return true.
6404///
6405/// @return true if the size attribute was found.
6406static bool
6407die_size_in_bits(const Dwarf_Die* die, uint64_t& size)
6408{
6409 if (!die)
6410 return false;
6411
6412 uint64_t byte_size = 0, bit_size = 0;
6413
6414 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6415 {
6416 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6417 return false;
6418 }
6419 else
6420 bit_size = byte_size * 8;
6421
6422 size = bit_size;
6423
6424 return true;
6425}
6426
6427/// Get the access specifier (from the DW_AT_accessibility attribute
6428/// value) of a given DIE.
6429///
6430/// @param die the DIE to consider.
6431///
6432/// @param access the resulting access. This is set iff the function
6433/// returns true.
6434///
6435/// @return bool if the DIE contains the DW_AT_accessibility die.
6436static bool
6437die_access_specifier(Dwarf_Die * die, access_specifier& access)
6438{
6439 if (!die)
6440 return false;
6441
6442 uint64_t a = 0;
6443 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6444 return false;
6445
6446 access_specifier result = private_access;
6447
6448 switch (a)
6449 {
6450 case private_access:
6451 result = private_access;
6452 break;
6453
6454 case protected_access:
6455 result = protected_access;
6456 break;
6457
6458 case public_access:
6459 result = public_access;
6460 break;
6461
6462 default:
6463 break;
6464 }
6465
6466 access = result;
6467 return true;
6468}
6469
6470/// Test whether a given DIE represents a decl that is public. That
6471/// is, one with the DW_AT_external attribute set.
6472///
6473/// @param die the DIE to consider for testing.
6474///
6475/// @return true if a DW_AT_external attribute is present and its
6476/// value is set to the true; return false otherwise.
6477static bool
6478die_is_public_decl(const Dwarf_Die* die)
6479{
6480 if (!die)
6481 return false;
6482 bool is_public = false;
6483
6484 // If this is a DW_TAG_subprogram DIE, look for the
6485 // DW_AT_external attribute on it. Otherwise, if it's a non-anonymous namespace,
6486 // then it's public. In all other cases, this should return false.
6487
6488 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6489 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6490 die_flag_attribute(die, DW_AT_external, is_public);
6491 else if (tag == DW_TAG_namespace)
6492 {
6493 string name = die_name(die);
6494 is_public = !name.empty();
6495 }
6496
6497 return is_public;
6498}
6499
6500/// Test if a DIE is effectively public.
6501///
6502/// This is meant to return true when either the DIE is public or when
6503/// it's a variable DIE that is at (global) namespace level.
6504///
6505/// @return true iff either the DIE is public or is a variable DIE
6506/// that is at (global) namespace level.
6507static bool
6508die_is_effectively_public_decl(const reader& rdr,
6509 const Dwarf_Die* die)
6510{
6511 if (die_is_public_decl(die))
6512 return true;
6513
6514 unsigned tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6515 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6516 {
6517 // The DIE is a variable.
6518 Dwarf_Die parent_die;
6519 size_t where_offset = 0;
6520 if (!get_parent_die(rdr, die, parent_die, where_offset))
6521 return false;
6522
6523 tag = dwarf_tag(&parent_die);
6524 if (tag == DW_TAG_compile_unit
6525 || tag == DW_TAG_partial_unit
6526 || tag == DW_TAG_type_unit)
6527 // The DIE is at global scope.
6528 return true;
6529
6530 if (tag == DW_TAG_namespace)
6531 {
6532 string name = die_name(&parent_die);
6533 if (name.empty())
6534 // The DIE at unnamed namespace scope, so it's not public.
6535 return false;
6536 // The DIE is at namespace scope.
6537 return true;
6538 }
6539 }
6540 return false;
6541}
6542
6543/// Test whether a given DIE represents a declaration-only DIE.
6544///
6545/// That is, if the DIE has the DW_AT_declaration flag set.
6546///
6547/// @param die the DIE to consider.
6548//
6549/// @return true if a DW_AT_declaration is present, false otherwise.
6550static bool
6551die_is_declaration_only(Dwarf_Die* die)
6552{
6553 bool is_declaration = false;
6554 die_flag_attribute(die, DW_AT_declaration, is_declaration, false);
6555 if (is_declaration && !die_has_size_attribute(die))
6556 return true;
6557 return false;
6558}
6559
6560/// Test if a DIE is for a function decl.
6561///
6562/// @param die the DIE to consider.
6563///
6564/// @return true iff @p die represents a function decl.
6565static bool
6566die_is_function_decl(const Dwarf_Die *die)
6567{
6568 if (!die)
6569 return false;
6570
6571 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6572 if (tag == DW_TAG_subprogram)
6573 return true;
6574 return false;
6575}
6576
6577/// Test if a DIE is for a variable decl.
6578///
6579/// @param die the DIE to consider.
6580///
6581/// @return true iff @p die represents a variable decl.
6582static bool
6583die_is_variable_decl(const Dwarf_Die *die)
6584{
6585 if (!die)
6586 return false;
6587
6588 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6589 if (tag == DW_TAG_variable)
6590 return true;
6591 return false;
6592}
6593
6594/// Test if a DIE has size attribute.
6595///
6596/// @param die the DIE to consider.
6597///
6598/// @return true if the DIE has a size attribute.
6599static bool
6600die_has_size_attribute(const Dwarf_Die *die)
6601{
6602 uint64_t s;
6603 if (die_size_in_bits(die, s))
6604 return true;
6605 return false;
6606}
6607
6608/// Test that a DIE has no child DIE.
6609///
6610/// @param die the DIE to consider.
6611///
6612/// @return true iff @p die has no child DIE.
6613static bool
6614die_has_no_child(const Dwarf_Die *die)
6615{
6616 if (!die)
6617 return true;
6618
6619 Dwarf_Die child;
6620 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
6621 return false;
6622 return true;
6623}
6624
6625/// Test whether a given DIE represents a declaration-only DIE.
6626///
6627/// That is, if the DIE has the DW_AT_declaration flag set.
6628///
6629/// @param die the DIE to consider.
6630//
6631/// @return true if a DW_AT_declaration is present, false otherwise.
6632static bool
6633die_is_declaration_only(const Dwarf_Die* die)
6634{return die_is_declaration_only(const_cast<Dwarf_Die*>(die));}
6635
6636/// Tests whether a given DIE is artificial.
6637///
6638/// @param die the test to test for.
6639///
6640/// @return true if the DIE is artificial, false otherwise.
6641static bool
6642die_is_artificial(Dwarf_Die* die)
6643{
6644 bool is_artificial;
6645 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6646}
6647
6648///@return true if a tag represents a type, false otherwise.
6649///
6650///@param tag the tag to consider.
6651static bool
6652is_type_tag(unsigned tag)
6653{
6654 bool result = false;
6655
6656 switch (tag)
6657 {
6658 case DW_TAG_array_type:
6659 case DW_TAG_class_type:
6660 case DW_TAG_enumeration_type:
6661 case DW_TAG_pointer_type:
6662 case DW_TAG_reference_type:
6663 case DW_TAG_string_type:
6664 case DW_TAG_structure_type:
6665 case DW_TAG_subroutine_type:
6666 case DW_TAG_typedef:
6667 case DW_TAG_union_type:
6668 case DW_TAG_ptr_to_member_type:
6669 case DW_TAG_set_type:
6670 case DW_TAG_subrange_type:
6671 case DW_TAG_base_type:
6672 case DW_TAG_const_type:
6673 case DW_TAG_file_type:
6674 case DW_TAG_packed_type:
6675 case DW_TAG_thrown_type:
6676 case DW_TAG_volatile_type:
6677 case DW_TAG_restrict_type:
6678 case DW_TAG_interface_type:
6679 case DW_TAG_unspecified_type:
6680 case DW_TAG_shared_type:
6681 case DW_TAG_rvalue_reference_type:
6682 case DW_TAG_coarray_type:
6683 case DW_TAG_atomic_type:
6684 case DW_TAG_immutable_type:
6685 result = true;
6686 break;
6687
6688 default:
6689 result = false;
6690 break;
6691 }
6692
6693 return result;
6694}
6695
6696/// Test if a given DIE is a type whose canonical type is to be
6697/// propagated during DIE canonicalization
6698///
6699/// This is a sub-routine of compare_dies.
6700///
6701/// @param tag the tag of the DIE to consider.
6702///
6703/// @return true iff the DIE of tag @p tag is can see its canonical
6704/// type be propagated during the type comparison that happens during
6705/// DIE canonicalization.
6706static bool
6707is_canon_type_to_be_propagated_tag(unsigned tag)
6708{
6709 bool result = false;
6710
6711 switch (tag)
6712 {
6713 case DW_TAG_class_type:
6714 case DW_TAG_structure_type:
6715 case DW_TAG_union_type:
6716 case DW_TAG_subroutine_type:
6717 case DW_TAG_subprogram:
6718 result = true;
6719 break;
6720
6721 default:
6722 result = false;
6723 break;
6724 }
6725
6726 return result;
6727}
6728
6729/// Test if a given kind of DIE ought to have its comparison result
6730/// cached by compare_dies, so that subsequent invocations of
6731/// compare_dies can be faster.
6732///
6733/// @param tag the tag of the DIE to consider.
6734///
6735/// @return true iff DIEs of the tag @p tag ought to have its
6736/// comparison results cached.
6737static bool
6738type_comparison_result_to_be_cached(unsigned tag)
6739{
6740 bool r = false;
6741 switch (tag)
6742 {
6743 case DW_TAG_class_type:
6744 case DW_TAG_structure_type:
6745 case DW_TAG_union_type:
6746 case DW_TAG_subroutine_type:
6747 case DW_TAG_subprogram:
6748 r = true;
6749 break;
6750
6751 default:
6752 r = false;
6753 break;
6754 }
6755 return r;
6756}
6757
6758/// Cache the result of comparing to type DIEs.
6759///
6760/// @param rdr the context to consider.
6761///
6762/// @param tag the tag of the DIEs to consider.
6763///
6764/// @param p the offsets of the pair of DIEs being compared.
6765///
6766/// @param result the comparison result to be cached.
6767static bool
6768maybe_cache_type_comparison_result(const reader& rdr,
6769 int tag,
6770 const offset_pair_type& p,
6771 comparison_result result)
6772{
6773 if (!type_comparison_result_to_be_cached(tag)
6774 || (result != COMPARISON_RESULT_EQUAL
6775 && result != COMPARISON_RESULT_DIFFERENT))
6776 return false;
6777
6778 rdr.die_comparison_results_[p] = result;
6779
6780 return true;
6781
6782}
6783
6784/// Get the cached result of the comparison of a pair of DIEs.
6785///
6786/// @param rdr the context to consider.
6787///
6788/// @param tag the tag of the pair of DIEs to consider.
6789///
6790/// @param p the offsets of the pair of DIEs to consider.
6791///
6792/// @param result out parameter set to the cached result of the
6793/// comparison of @p p if it has been found.
6794///
6795/// @return true iff a cached result for the comparisonof @p has been
6796/// found and set into @p result.
6797static bool
6798get_cached_type_comparison_result(const