14 #include "abg-internal.h"
15 #include <sys/types.h>
22 #include <elfutils/libdwfl.h>
33 #include <unordered_map>
34 #include <unordered_set>
43 ABG_BEGIN_EXPORT_DECLARATIONS
51 ABG_END_EXPORT_DECLARATIONS
55 #define UINT64_MAX 0xffffffffffffffff
69 using std::dynamic_pointer_cast;
70 using std::static_pointer_cast;
71 using std::unordered_map;
72 using std::unordered_set;
79 using namespace elf_helpers;
86 NO_DEBUG_INFO_DIE_SOURCE,
87 PRIMARY_DEBUG_INFO_DIE_SOURCE,
88 ALT_DEBUG_INFO_DIE_SOURCE,
90 NUMBER_OF_DIE_SOURCES,
138 struct dwarf_offset_pair_hash
141 operator()(
const std::pair<Dwarf_Off, Dwarf_Off>& p)
const
142 {
return abigail::hashing::combine_hashes(p.first, p.second);}
145 typedef unordered_set<std::pair<Dwarf_Off,
147 dwarf_offset_pair_hash> dwarf_offset_pair_set_type;
157 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
161 offset_type(
die_source source, Dwarf_Off offset)
166 offset_type(Dwarf_Off offset)
167 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
172 {
return source_ == o.source_ && offset_ == o.offset_;}
174 operator Dwarf_Off()
const
185 operator()(
const offset_type& p)
const
186 {
return abigail::hashing::combine_hashes(p.source_, p.offset_);}
191 struct offset_pair_hash
194 operator()(
const std::pair<offset_type, offset_type>& p)
const
196 size_t h1 = abigail::hashing::combine_hashes(p.first.source_,
198 size_t h2 = abigail::hashing::combine_hashes(p.second.source_,
200 return abigail::hashing::combine_hashes(h1, h2);
208 typedef unordered_set<std::pair<offset_type,
217 typedef unordered_map<std::pair<offset_type, offset_type>,
223 typedef unordered_map<std::pair<offset_type, offset_type>,
233 build_translation_unit_and_add_to_ir(reader& rdr,
238 maybe_propagate_canonical_type(
const reader& rdr,
243 propagate_canonical_type(
const reader& rdr,
285 struct imported_unit_point
287 Dwarf_Off offset_of_import;
291 Dwarf_Off imported_unit_die_off;
292 Dwarf_Off imported_unit_cu_off;
293 Dwarf_Off imported_unit_child_off;
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()
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()
324 imported_unit_point(Dwarf_Off import_off,
325 const Dwarf_Die& imported_die,
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()
334 Dwarf_Die imported_unit_child;
336 ABG_ASSERT(dwarf_child(
const_cast<Dwarf_Die*
>(&imported_die),
337 &imported_unit_child) == 0);
339 imported_unit_child_off =
340 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(&imported_unit_child));
342 Dwarf_Die cu_die_memory;
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);
355 typedef unordered_map<Dwarf_Off, imported_unit_points_type>
367 operator<(
const imported_unit_point& l,
const imported_unit_point& r)
368 {
return l.offset_of_import < r.offset_of_import;}
371 get_parent_die(
const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
377 get_scope_die(
const reader& rdr,
378 const Dwarf_Die* die,
380 Dwarf_Die& scope_die);
386 die_is_in_c(
const Dwarf_Die *die);
389 die_is_in_cplus_plus(
const Dwarf_Die *die);
392 die_is_in_c_or_cplusplus(
const Dwarf_Die *die);
395 die_is_anonymous(
const Dwarf_Die* die);
398 die_is_anonymous_data_member(
const Dwarf_Die* die);
401 die_is_type(
const Dwarf_Die* die);
404 die_is_decl(
const Dwarf_Die* die);
407 die_is_declaration_only(Dwarf_Die* die);
410 die_is_variable_decl(
const Dwarf_Die *die);
413 die_is_function_decl(
const Dwarf_Die *die);
416 die_has_size_attribute(
const Dwarf_Die *die);
419 die_has_no_child(
const Dwarf_Die *die);
422 die_is_namespace(
const Dwarf_Die* die);
425 die_is_unspecified(Dwarf_Die* die);
428 die_is_void_type(Dwarf_Die* die);
431 die_is_pointer_type(
const Dwarf_Die* die);
434 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
437 die_is_reference_type(
const Dwarf_Die* die);
440 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
443 die_is_pointer_or_reference_type(
const Dwarf_Die* die);
446 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
449 die_is_class_type(
const Dwarf_Die* die);
452 die_is_qualified_type(
const Dwarf_Die* die);
455 die_is_function_type(
const Dwarf_Die *die);
458 die_has_object_pointer(
const Dwarf_Die* die,
459 Dwarf_Die& object_pointer);
462 die_has_children(
const Dwarf_Die* die);
465 die_this_pointer_from_object_pointer(Dwarf_Die* die,
466 Dwarf_Die& this_pointer);
469 die_this_pointer_is_const(Dwarf_Die* die);
472 die_object_pointer_is_for_const_method(Dwarf_Die* die);
475 is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
478 die_is_at_class_scope(
const reader& rdr,
479 const Dwarf_Die* die,
481 Dwarf_Die& class_scope_die);
483 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
486 bool& is_tls_address);
489 dwarf_language_to_tu_language(
size_t l);
492 die_unsigned_constant_attribute(
const Dwarf_Die* die,
497 die_signed_constant_attribute(
const Dwarf_Die*die,
502 die_constant_attribute(
const Dwarf_Die *die,
505 array_type_def::subrange_type::bound_value &value);
508 die_member_offset(
const reader& rdr,
509 const Dwarf_Die* die,
513 form_is_DW_FORM_strx(
unsigned form);
516 form_is_DW_FORM_line_strp(
unsigned form);
519 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
522 die_name(
const Dwarf_Die* die);
525 die_name_and_linkage_name(
const Dwarf_Die* die,
527 string& linkage_name);
529 die_location(
const reader& rdr,
const Dwarf_Die* die);
532 die_location_address(Dwarf_Die* die,
534 bool& is_tls_address);
537 die_die_attribute(
const Dwarf_Die* die,
540 bool recursively =
true);
543 die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
546 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
548 array_type_def::subrange_type::bound_value& v,
552 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
554 Dwarf_Die& referenced_subrange);
556 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
559 build_internal_anonymous_die_name(
const string &
base_name,
560 size_t anonymous_type_index);
563 get_internal_anonymous_die_name(Dwarf_Die *die,
564 size_t anonymous_type_index);
567 die_qualified_type_name(
const reader& rdr,
568 const Dwarf_Die* die,
572 die_qualified_decl_name(
const reader& rdr,
573 const Dwarf_Die* die,
577 die_qualified_name(
const reader& rdr,
578 const Dwarf_Die* die,
582 die_qualified_type_name_empty(
const reader& rdr,
583 const Dwarf_Die* die,
size_t where,
584 string &qualified_name);
587 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
588 const Dwarf_Die* die,
591 string &return_type_name,
593 vector<string>& parm_names,
598 die_function_signature(
const reader& rdr,
599 const Dwarf_Die *die,
600 size_t where_offset);
603 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
606 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
609 die_function_type_is_method_type(
const reader& rdr,
610 const Dwarf_Die *die,
612 Dwarf_Die& object_pointer_die,
613 Dwarf_Die& class_die,
617 die_pretty_print_type(reader& rdr,
618 const Dwarf_Die* die,
619 size_t where_offset);
622 die_pretty_print_decl(reader& rdr,
623 const Dwarf_Die* die,
624 size_t where_offset);
627 die_pretty_print(reader& rdr,
628 const Dwarf_Die* die,
629 size_t where_offset);
632 maybe_canonicalize_type(
const type_base_sptr& t,
641 imported_unit_points_type::const_iterator&);
644 build_subrange_type(reader& rdr,
645 const Dwarf_Die* die,
647 bool associate_type_to_die =
true);
650 build_subranges_from_array_type_die(reader& rdr,
651 const Dwarf_Die* die,
654 bool associate_type_to_die =
true);
657 compare_dies(
const reader& rdr,
658 const Dwarf_Die *l,
const Dwarf_Die *r,
659 bool update_canonical_dies_on_the_fly);
662 compare_dies_during_canonicalization(reader& rdr,
663 const Dwarf_Die *l,
const Dwarf_Die *r,
664 bool update_canonical_dies_on_the_fly);
667 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
680 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
683 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
686 lang = dwarf_language_to_tu_language(l);
698 die_is_in_c(
const Dwarf_Die *die)
701 if (!get_die_language(die, l))
714 die_is_in_cplus_plus(
const Dwarf_Die *die)
717 if (!get_die_language(die, l))
730 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
733 if (!get_die_language(die, l))
750 compare_symbol_name(
const string& symbol_name,
759 return symbol_name == name;
788 lookup_symbol_from_sysv_hash_tab(
const environment& env,
790 const string& sym_name,
792 size_t sym_tab_index,
794 vector<elf_symbol_sptr>& syms_found)
796 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
799 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
802 GElf_Shdr sheader_mem;
803 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
805 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
810 unsigned long hash = elf_hash(sym_name.c_str());
811 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
812 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
813 size_t nb_buckets = ht_data[0];
814 size_t nb_chains = ht_data[1];
822 Elf32_Word* ht_buckets = &ht_data[2];
823 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
826 size_t bucket = hash % nb_buckets;
827 size_t symbol_index = ht_buckets[bucket];
830 const char* sym_name_str;
839 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
840 sym_name_str = elf_strptr(elf_handle,
841 sym_tab_section_header->sh_link,
844 && compare_symbol_name(sym_name_str, sym_name, demangle))
850 sym_size = symbol.st_size;
851 elf_symbol::version ver;
862 symbol.st_shndx != SHN_UNDEF,
863 symbol.st_shndx == SHN_COMMON,
864 ver, sym_visibility);
865 syms_found.push_back(symbol_found);
868 symbol_index = ht_chains[symbol_index];
869 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
880 get_elf_class_size_in_bytes(Elf* elf_handle)
886 int c = hdr.e_ident[EI_CLASS];
920 bloom_word_at(Elf* elf_handle,
921 Elf32_Word* bloom_filter,
924 Elf64_Xword result = 0;
928 c = h.e_ident[EI_CLASS];
933 result = bloom_filter[index];
937 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
958 size_t first_sym_index;
961 Elf32_Word* bloom_filter;
964 Elf_Scn* sym_tab_section;
965 GElf_Shdr sym_tab_section_header;
995 setup_gnu_ht(Elf* elf_handle,
997 size_t sym_tab_index,
1000 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1002 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
1004 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
1005 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
1010 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
1011 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
1013 ht.nb_buckets = ht_data[0];
1014 if (ht.nb_buckets == 0)
1018 ht.first_sym_index = ht_data[1];
1021 ht.bf_nwords = ht_data[2];
1023 ht.shift = ht_data[3];
1025 ht.bloom_filter = &ht_data[4];
1030 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
1032 ht.buckets = ht.bloom_filter + ht.bf_size;
1034 ht.chain = ht.buckets + ht.nb_buckets;
1065 lookup_symbol_from_gnu_hash_tab(
const environment& env,
1067 const string& sym_name,
1069 size_t sym_tab_index,
1071 vector<elf_symbol_sptr>& syms_found)
1074 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
1080 size_t h1 = elf_gnu_hash(sym_name.c_str());
1081 size_t h2 = h1 >> ht.shift;
1084 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1085 int n = (h1 / c) % ht.bf_nwords;
1091 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1094 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1097 size_t i = ht.buckets[h1 % ht.nb_buckets];
1101 Elf32_Word stop_word, *stop_wordp;
1102 elf_symbol::version ver;
1104 const char* sym_name_str;
1113 for (i = ht.buckets[h1 % ht.nb_buckets],
1114 stop_wordp = &ht.chain[i - ht.first_sym_index];
1117 < ht.chain + (ht.sym_count - ht.first_sym_index));
1120 stop_word = *stop_wordp;
1121 if ((stop_word & ~ 1)!= (h1 & ~1))
1127 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1129 sym_name_str = elf_strptr(elf_handle,
1130 ht.sym_tab_section_header.sh_link,
1133 && compare_symbol_name(sym_name_str, sym_name, demangle))
1151 sym_type, sym_binding,
1152 symbol.st_shndx != SHN_UNDEF,
1153 symbol.st_shndx == SHN_COMMON,
1154 ver, sym_visibility);
1155 syms_found.push_back(symbol_found);
1197 lookup_symbol_from_elf_hash_tab(
const environment& env,
1199 hash_table_kind ht_kind,
1201 size_t symtab_index,
1202 const string& symbol_name,
1204 vector<elf_symbol_sptr>& syms_found)
1206 if (elf_handle == 0 || symbol_name.empty())
1209 if (ht_kind == NO_HASH_TABLE_KIND)
1212 if (ht_kind == SYSV_HASH_TABLE_KIND)
1213 return lookup_symbol_from_sysv_hash_tab(env,
1214 elf_handle, symbol_name,
1219 else if (ht_kind == GNU_HASH_TABLE_KIND)
1220 return lookup_symbol_from_gnu_hash_tab(env,
1221 elf_handle, symbol_name,
1254 lookup_symbol_from_symtab(
const environment& env,
1256 const string& sym_name,
1257 size_t sym_tab_index,
1259 vector<elf_symbol_sptr>& syms_found)
1264 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1267 GElf_Shdr header_mem;
1268 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1271 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1272 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1275 elf_symbol::version ver;
1278 for (
size_t i = 0; i < symcount; ++i)
1281 sym = gelf_getsym(symtab, i, &sym_mem);
1282 name_str = elf_strptr(elf_handle,
1283 sym_tab_header->sh_link,
1286 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1294 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1295 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1304 sym_binding, sym_is_defined,
1305 sym_is_common, ver, sym_visibility);
1306 syms_found.push_back(symbol_found);
1345 lookup_symbol_from_elf(
const environment& env,
1347 const string& symbol_name,
1349 vector<elf_symbol_sptr>& syms_found)
1351 size_t hash_table_index = 0, symbol_table_index = 0;
1352 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1357 symbol_table_index);
1359 if (ht_kind == NO_HASH_TABLE_KIND)
1364 return lookup_symbol_from_symtab(env,
1372 return lookup_symbol_from_elf_hash_tab(env,
1396 lookup_public_function_symbol_from_elf(environment& env,
1398 const string& symbol_name,
1399 vector<elf_symbol_sptr>& func_syms)
1401 vector<elf_symbol_sptr> syms_found;
1404 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1407 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1408 i != syms_found.end();
1414 if ((type == elf_symbol::FUNC_TYPE
1415 || type == elf_symbol::GNU_IFUNC_TYPE
1416 || type == elf_symbol::COMMON_TYPE)
1417 && (binding == elf_symbol::GLOBAL_BINDING
1418 || binding == elf_symbol::WEAK_BINDING))
1420 func_syms.push_back(*i);
1441 int64_t const_value_;
1449 expr_result(
bool is_const)
1450 : is_const_(is_const),
1454 explicit expr_result(int64_t v)
1480 const_value(int64_t& value)
1484 value = const_value_;
1500 return const_value_;
1503 operator int64_t()
const
1504 {
return const_value();}
1507 operator=(
const int64_t v)
1515 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1518 operator>=(
const expr_result& o)
const
1519 {
return const_value_ >= o.const_value_;}
1522 operator<=(
const expr_result& o)
const
1523 {
return const_value_ <= o.const_value_;}
1526 operator>(
const expr_result& o)
const
1527 {
return const_value_ > o.const_value_;}
1530 operator<(
const expr_result& o)
const
1531 {
return const_value_ < o.const_value_;}
1536 expr_result r(*
this);
1537 r.const_value_ += v.const_value_;
1538 r.is_const_ = r.is_const_ && v.is_const_;
1543 operator+=(int64_t v)
1550 operator-(
const expr_result& v)
const
1552 expr_result r(*
this);
1553 r.const_value_ -= v.const_value_;
1554 r.is_const_ = r.is_const_ && v.is_const_;
1559 operator%(
const expr_result& v)
const
1561 expr_result r(*
this);
1562 r.const_value_ %= v.const_value_;
1563 r.is_const_ = r.is_const_ && v.is_const();
1568 operator*(
const expr_result& v)
const
1570 expr_result r(*
this);
1571 r.const_value_ *= v.const_value_;
1572 r.is_const_ = r.is_const_ && v.is_const();
1579 expr_result r(*
this);
1580 r.const_value_ |= v.const_value_;
1581 r.is_const_ = r.is_const_ && v.is_const_;
1586 operator^(
const expr_result& v)
const
1588 expr_result r(*
this);
1589 r.const_value_ ^= v.const_value_;
1590 r.is_const_ = r.is_const_ && v.is_const_;
1595 operator>>(
const expr_result& v)
const
1597 expr_result r(*
this);
1598 r.const_value_ = r.const_value_ >> v.const_value_;
1599 r.is_const_ = r.is_const_ && v.is_const_;
1606 expr_result r(*
this);
1607 r.const_value_ = r.const_value_ << v.const_value_;
1608 r.is_const_ = r.is_const_ && v.is_const_;
1615 expr_result r(*
this);
1616 r.const_value_ = ~r.const_value_;
1623 expr_result r(*
this);
1624 r.const_value_ = -r.const_value_;
1631 expr_result r = *
this;
1632 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1639 expr_result r(*
this);
1640 r.const_value_ &= o.const_value_;
1641 r.is_const_ = r.is_const_ && o.is_const_;
1646 operator/(
const expr_result& o)
1648 expr_result r(*
this);
1649 r.is_const_ = r.is_const_ && o.is_const_;
1650 return r.const_value() / o.const_value();
1656 class expr_result_stack_type
1658 vector<expr_result> elems_;
1662 expr_result_stack_type()
1663 {elems_.reserve(4);}
1666 operator[](
unsigned i)
1668 unsigned s = elems_.size();
1670 return elems_[s - 1 -i];
1674 operator[](
unsigned i)
const
1675 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1679 {
return elems_.size();}
1681 vector<expr_result>::reverse_iterator
1683 {
return elems_.rbegin();}
1685 const vector<expr_result>::reverse_iterator
1687 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1689 vector<expr_result>::reverse_iterator
1691 {
return elems_.rend();}
1693 const vector<expr_result>::reverse_iterator
1695 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1699 {
return elems_.back();}
1703 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1706 push_front(expr_result e)
1707 {elems_.push_back(e);}
1712 expr_result r = front();
1718 erase(vector<expr_result>::reverse_iterator i)
1719 {elems_.erase(--i.base());}
1727 struct dwarf_expr_eval_context
1730 expr_result_stack_type stack;
1735 dwarf_expr_eval_context()
1739 stack.push_front(expr_result(
true));
1746 stack.push_front(expr_result(
true));
1747 accum = expr_result(
false);
1748 set_tls_addr =
false;
1757 set_tls_address(
bool f)
1766 set_tls_address()
const
1767 {
return set_tls_addr;}
1772 expr_result r = stack.front();
1778 push(
const expr_result& v)
1779 {stack.push_front(v);}
1788 typedef shared_ptr<reader> reader_sptr;
1795 class reader :
public elf_based_reader
1802 template <
typename ContainerType>
1803 class die_source_dependant_container_set
1805 ContainerType primary_debug_info_container_;
1806 ContainerType alt_debug_info_container_;
1807 ContainerType type_unit_container_;
1821 ContainerType *result = 0;
1824 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1825 result = &primary_debug_info_container_;
1827 case ALT_DEBUG_INFO_DIE_SOURCE:
1828 result = &alt_debug_info_container_;
1830 case TYPE_UNIT_DIE_SOURCE:
1831 result = &type_unit_container_;
1833 case NO_DEBUG_INFO_DIE_SOURCE:
1834 case NUMBER_OF_DIE_SOURCES:
1847 const ContainerType&
1850 return const_cast<die_source_dependant_container_set*
>(
this)->
1851 get_container(source);
1865 get_container(
const reader& rdr,
const Dwarf_Die *die)
1867 const die_source source = rdr.get_die_source(die);
1868 return get_container(source);
1881 const ContainerType&
1882 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1884 return const_cast<die_source_dependant_container_set*
>(
this)->
1885 get_container(rdr, die);
1892 primary_debug_info_container_.clear();
1893 alt_debug_info_container_.clear();
1894 type_unit_container_.clear();
1898 unsigned short dwarf_version_;
1899 Dwarf_Die* cur_tu_die_;
1900 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1904 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1905 decl_die_repr_die_offsets_maps_;
1909 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1910 type_die_repr_die_offsets_maps_;
1911 mutable die_source_dependant_container_set<die_istring_map_type>
1912 die_qualified_name_maps_;
1913 mutable die_source_dependant_container_set<die_istring_map_type>
1914 die_pretty_repr_maps_;
1915 mutable die_source_dependant_container_set<die_istring_map_type>
1916 die_pretty_type_repr_maps_;
1919 mutable die_source_dependant_container_set<die_artefact_map_type>
1920 decl_die_artefact_maps_;
1923 mutable die_source_dependant_container_set<die_artefact_map_type>
1924 type_die_artefact_maps_;
1927 mutable die_source_dependant_container_set<offset_offset_map_type>
1928 canonical_type_die_offsets_;
1931 mutable die_source_dependant_container_set<offset_offset_map_type>
1932 canonical_decl_die_offsets_;
1938 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1940 dwarf_offset_pair_hash> die_comparison_results_;
1950 vector<type_base_sptr> types_to_canonicalize_;
1969 list<var_decl_sptr> var_decls_to_add_;
1970 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1971 bool debug_die_canonicalization_is_on_;
1972 bool use_canonical_die_comparison_;
1974 mutable size_t compare_count_;
1975 mutable size_t canonical_propagated_count_;
1976 mutable size_t cancelled_propagation_count_;
1977 mutable optional<bool> leverage_dwarf_factorization_;
2012 reader(
const string& elf_path,
2013 const vector<char**>& debug_info_root_paths,
2014 environment& environment,
2015 bool load_all_types,
2016 bool linux_kernel_mode)
2017 : elf_based_reader(elf_path,
2018 debug_info_root_paths,
2021 initialize(load_all_types, linux_kernel_mode);
2039 initialize(
bool load_all_types,
bool linux_kernel_mode)
2043 decl_die_repr_die_offsets_maps_.clear();
2044 type_die_repr_die_offsets_maps_.clear();
2045 die_qualified_name_maps_.clear();
2046 die_pretty_repr_maps_.clear();
2047 die_pretty_type_repr_maps_.clear();
2048 decl_die_artefact_maps_.clear();
2049 type_die_artefact_maps_.clear();
2050 canonical_type_die_offsets_.clear();
2051 canonical_decl_die_offsets_.clear();
2052 die_wip_classes_map_.clear();
2053 alternate_die_wip_classes_map_.clear();
2054 type_unit_die_wip_classes_map_.clear();
2055 die_wip_function_types_map_.clear();
2056 alternate_die_wip_function_types_map_.clear();
2057 type_unit_die_wip_function_types_map_.clear();
2058 die_function_with_no_symbol_map_.clear();
2059 types_to_canonicalize_.clear();
2060 decl_only_classes_map_.clear();
2061 die_tu_map_.clear();
2063 corpus_group().reset();
2065 primary_die_parent_map_.clear();
2066 tu_die_imported_unit_points_map_.clear();
2067 alt_tu_die_imported_unit_points_map_.clear();
2068 type_units_tu_die_imported_unit_points_map_.clear();
2069 alternate_die_parent_map_.clear();
2070 type_section_die_parent_map_.clear();
2071 var_decls_to_add_.clear();
2072 clear_per_translation_unit_data();
2073 options().load_in_linux_kernel_mode = linux_kernel_mode;
2074 options().load_all_types = load_all_types;
2075 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2076 debug_die_canonicalization_is_on_ =
2077 env().debug_die_canonicalization_is_on();
2078 use_canonical_die_comparison_ =
true;
2081 canonical_propagated_count_ = 0;
2082 cancelled_propagation_count_ = 0;
2083 load_in_linux_kernel_mode(linux_kernel_mode);
2105 const vector<char**>& debug_info_root_paths,
2106 bool load_all_types,
2107 bool linux_kernel_mode)
2110 initialize(load_all_types, linux_kernel_mode);
2130 static dwarf::reader_sptr
2131 create(
const std::string& elf_path,
2132 const vector<char**>& debug_info_root_paths,
2133 environment& environment,
2134 bool load_all_types,
2135 bool linux_kernel_mode)
2137 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2138 environment, load_all_types,
2139 linux_kernel_mode));
2156 read_corpus(status& status)
2158 status = STATUS_UNKNOWN;
2163 if (!(status & STATUS_OK))
2167 return corpus_sptr();
2171 if (dwarf_debug_info() ==
nullptr)
2172 status |= STATUS_DEBUG_INFO_NOT_FOUND;
2176 if (refers_to_alt_debug_info(alt_di_path)
2177 && !alternate_dwarf_debug_info())
2178 status |= STATUS_ALT_DEBUG_INFO_NOT_FOUND;
2183 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2184 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2186 return corpus_sptr();
2190 corpus_sptr corp = read_debug_info_into_corpus();
2192 status |= STATUS_OK;
2205 read_debug_info_into_corpus()
2207 clear_per_corpus_data();
2212 origin |= corpus::DWARF_ORIGIN;
2213 corpus()->set_origin(origin);
2215 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2216 && !env().user_set_analyze_exported_interfaces_only())
2223 env().analyze_exported_interfaces_only(
true);
2225 corpus()->set_soname(dt_soname());
2226 corpus()->set_needed(dt_needed());
2227 corpus()->set_architecture_name(elf_architecture());
2229 corpus()->set_symtab(symtab());
2233 if (!dwarf_debug_info()
2234 || !corpus()->get_symtab()
2235 || !corpus()->get_symtab()->has_symbols())
2238 uint8_t address_size = 0;
2239 size_t header_size = 0;
2241 #ifdef WITH_DEBUG_SELF_COMPARISON
2242 if (env().self_comparison_debug_is_on())
2243 env().set_self_comparison_debug_input(corpus());
2246 env().priv_->do_log(do_log());
2251 tools_utils::timer t;
2254 cerr <<
"building die -> parent maps ...";
2258 build_die_parent_maps();
2263 cerr <<
" DONE@" << corpus()->get_path()
2270 env().canonicalization_is_done(
false);
2273 tools_utils::timer t;
2276 cerr <<
"building the libabigail internal representation ...\n";
2280 Dwarf_Half dwarf_vers = 0;
2281 for (Dwarf_Off offset = 0, next_offset = 0;
2282 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
2283 offset, &next_offset, &header_size,
2284 &dwarf_vers, NULL, &address_size, NULL,
2286 offset = next_offset)
2288 Dwarf_Off die_offset = offset + header_size;
2290 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
2292 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2295 dwarf_version(dwarf_vers);
2302 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2308 cerr <<
"building the libabigail internal representation "
2309 <<
"DONE for corpus << corpus()->get_path()"
2314 cerr <<
"Number of aggregate types compared: "
2315 << compare_count_ <<
"\n"
2316 <<
"Number of canonical types propagated: "
2317 << canonical_propagated_count_ <<
"\n"
2318 <<
"Number of cancelled propagated canonical types:"
2319 << cancelled_propagation_count_ <<
"\n";
2324 tools_utils::timer t;
2327 cerr <<
"resolving declaration only classes ...";
2330 resolve_declaration_only_classes();
2334 cerr <<
" DONE@" << corpus()->get_path()
2342 tools_utils::timer t;
2345 cerr <<
"resolving declaration only enums ...";
2348 resolve_declaration_only_enums();
2352 cerr <<
" DONE@" << corpus()->get_path()
2360 tools_utils::timer t;
2363 cerr <<
"fixing up functions with linkage name but "
2364 <<
"no advertised underlying symbols ....";
2367 fixup_functions_with_no_symbols();
2371 cerr <<
" DONE@" << corpus()->get_path()
2390 tools_utils::timer t;
2393 cerr <<
"perform late type canonicalizing ...\n";
2397 perform_late_type_canonicalizing();
2401 cerr <<
"late type canonicalizing DONE for "
2402 << corpus()->get_path()
2409 env().canonicalization_is_done(
true);
2412 tools_utils::timer t;
2415 cerr <<
"sort functions and variables ...";
2418 corpus()->sort_functions();
2419 corpus()->sort_variables();
2423 cerr <<
" DONE@" << corpus()->get_path()
2437 clear_per_translation_unit_data()
2439 while (!scope_stack().empty())
2440 scope_stack().pop();
2441 var_decls_to_re_add_to_tree().clear();
2442 per_tu_repr_to_fn_type_maps().clear();
2448 clear_per_corpus_data()
2450 die_qualified_name_maps_.clear();
2451 die_pretty_repr_maps_.clear();
2452 die_pretty_type_repr_maps_.clear();
2453 clear_types_to_canonicalize();
2461 {
return options().env;}
2468 {
return const_cast<reader*
>(
this)->env();}
2476 drop_undefined_syms()
const
2477 {
return options().drop_undefined_syms;}
2484 drop_undefined_syms(
bool f)
2485 {options().drop_undefined_syms = f;}
2489 dwarf_version()
const
2490 {
return dwarf_version_;}
2493 dwarf_version(
unsigned short v)
2494 {dwarf_version_ = v;}
2506 dwarf_elf_handle()
const
2507 {
return dwarf_getelf(
const_cast<Dwarf*
>(dwarf_debug_info()));}
2517 dwarf_is_splitted()
const
2518 {
return dwarf_elf_handle() != elf_handle();}
2527 dwarf_per_die_source(
die_source source)
const
2529 const Dwarf *result = 0;
2532 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2533 case TYPE_UNIT_DIE_SOURCE:
2534 result = dwarf_debug_info();
2536 case ALT_DEBUG_INFO_DIE_SOURCE:
2537 result = alternate_dwarf_debug_info();
2539 case NO_DEBUG_INFO_DIE_SOURCE:
2540 case NUMBER_OF_DIE_SOURCES:
2551 {
return corpus_path();}
2555 {
return cur_tu_die_;}
2558 cur_tu_die(Dwarf_Die* cur_tu_die)
2559 {cur_tu_die_ = cur_tu_die;}
2561 dwarf_expr_eval_context&
2562 dwarf_expr_eval_ctxt()
const
2563 {
return dwarf_expr_eval_context_;}
2570 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2571 decl_die_repr_die_offsets_maps()
const
2572 {
return decl_die_repr_die_offsets_maps_;}
2579 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2580 decl_die_repr_die_offsets_maps()
2581 {
return decl_die_repr_die_offsets_maps_;}
2588 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2589 type_die_repr_die_offsets_maps()
const
2590 {
return type_die_repr_die_offsets_maps_;}
2597 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2598 type_die_repr_die_offsets_maps()
2599 {
return type_die_repr_die_offsets_maps_;}
2612 compute_canonical_die_offset(
const Dwarf_Die *die,
2613 Dwarf_Off &canonical_die_offset,
2614 bool die_as_type)
const
2618 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2619 get_container(*
this, die)
2620 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2621 get_container(*
this, die);
2623 Dwarf_Die canonical_die;
2624 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2626 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2644 compute_canonical_die(
const Dwarf_Die *die,
2646 Dwarf_Die &canonical_die,
2647 bool die_as_type)
const
2649 const die_source source = get_die_source(die);
2651 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2653 compute_canonical_die(die_offset, source,
2655 canonical_die, die_as_type);
2675 compute_canonical_die(Dwarf_Off die_offset,
2678 Dwarf_Die &canonical_die,
2679 bool die_as_type)
const
2685 ? (
const_cast<reader*
>(
this)->
2686 type_die_repr_die_offsets_maps().get_container(source))
2687 : (
const_cast<reader*
>(
this)->
2688 decl_die_repr_die_offsets_maps().get_container(source));
2691 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2700 interned_string name =
2702 ? get_die_pretty_type_representation(&die, 0)
2703 : get_die_pretty_representation(&die, 0);
2705 Dwarf_Off canonical_die_offset = 0;
2706 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2710 offsets.push_back(die_offset);
2711 map[name] = offsets;
2712 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2713 get_die_from_offset(source, die_offset, &canonical_die);
2717 Dwarf_Off cur_die_offset;
2718 Dwarf_Die potential_canonical_die;
2719 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2720 o != i->second.end();
2723 cur_die_offset = *o;
2724 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2725 if (compare_dies(*
this, &die, &potential_canonical_die,
2728 canonical_die_offset = cur_die_offset;
2729 set_canonical_die_offset(canonical_dies, die_offset,
2730 canonical_die_offset);
2731 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2736 canonical_die_offset = die_offset;
2737 i->second.push_back(die_offset);
2738 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2739 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2758 get_canonical_die(
const Dwarf_Die *die,
2759 Dwarf_Die &canonical_die,
2763 const die_source source = get_die_source(die);
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);
2772 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2773 if (Dwarf_Off canonical_die_offset =
2774 get_canonical_die_offset(canonical_dies, die_offset))
2776 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2784 ? (
const_cast<reader*
>(
this)->
2785 type_die_repr_die_offsets_maps().get_container(*
this, die))
2786 : (
const_cast<reader*
>(
this)->
2787 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2795 interned_string name =
2797 ? get_die_pretty_type_representation(die, where)
2798 : get_die_pretty_representation(die, where);
2800 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2804 Dwarf_Off cur_die_offset;
2805 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2806 o != i->second.end();
2809 cur_die_offset = *o;
2810 get_die_from_offset(source, cur_die_offset, &canonical_die);
2812 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2813 die, &canonical_die,
2816 set_canonical_die_offset(canonical_dies,
2850 get_or_compute_canonical_die(
const Dwarf_Die* die,
2851 Dwarf_Die& canonical_die,
2853 bool die_as_type)
const
2855 const die_source source = get_die_source(die);
2859 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2860 get_container(source)
2861 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2862 get_container(source);
2864 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2866 if (Dwarf_Off canonical_die_offset =
2867 get_canonical_die_offset(canonical_dies,
2868 initial_die_offset))
2870 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2874 if (!is_type_die_to_be_canonicalized(die))
2881 ? (
const_cast<reader*
>(
this)->
2882 type_die_repr_die_offsets_maps().get_container(*
this, die))
2883 : (
const_cast<reader*
>(
this)->
2884 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2892 interned_string name =
2894 ? get_die_pretty_type_representation(die, where)
2895 : get_die_pretty_representation(die, where);
2897 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2901 offsets.push_back(initial_die_offset);
2902 map[name] = offsets;
2903 get_die_from_offset(source, initial_die_offset, &canonical_die);
2904 set_canonical_die_offset(canonical_dies,
2906 initial_die_offset);
2913 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2916 Dwarf_Off die_offset = i->second[n];
2917 get_die_from_offset(source, die_offset, &canonical_die);
2919 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2920 die, &canonical_die,
2923 set_canonical_die_offset(canonical_dies,
2933 get_die_from_offset(source, initial_die_offset, &canonical_die);
2934 i->second.push_back(initial_die_offset);
2935 set_canonical_die_offset(canonical_dies,
2937 initial_die_offset);
2954 get_die_source(
const Dwarf_Die *die)
const
2956 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2977 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2981 uint8_t address_size = 0, offset_size = 0;
2982 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2983 &cu_die, &address_size,
2987 Dwarf_Half version = 0;
2988 Dwarf_Off abbrev_offset = 0;
2989 uint64_t type_signature = 0;
2990 Dwarf_Off type_offset = 0;
2991 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2992 &version, &abbrev_offset,
2993 &address_size, &offset_size,
2994 &type_signature, &type_offset))
2997 int tag = dwarf_tag(&cu_kind);
2999 if (tag == DW_TAG_compile_unit
3000 || tag == DW_TAG_partial_unit)
3002 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
3003 if (dwarf_debug_info() == die_dwarf)
3004 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
3005 else if (alternate_dwarf_debug_info() == die_dwarf)
3006 source = ALT_DEBUG_INFO_DIE_SOURCE;
3010 else if (tag == DW_TAG_type_unit)
3011 source = TYPE_UNIT_DIE_SOURCE;
3027 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
3029 if (source == TYPE_UNIT_DIE_SOURCE)
3030 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3033 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3060 associate_die_to_decl(Dwarf_Die* die,
3061 decl_base_sptr decl,
3062 size_t where_offset,
3063 bool do_associate_by_repr =
false)
3065 const die_source source = get_die_source(die);
3068 decl_die_artefact_maps().get_container(source);
3071 if (do_associate_by_repr)
3073 Dwarf_Die equiv_die;
3074 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
3077 die_offset = dwarf_dieoffset(&equiv_die);
3080 die_offset = dwarf_dieoffset(die);
3082 m[die_offset] = decl;
3104 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3106 decl_base_sptr result =
3107 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3126 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3130 die_qualified_name_maps_.get_container(*
this, die);
3132 size_t die_offset = dwarf_dieoffset(die);
3133 die_istring_map_type::const_iterator i = map.find(die_offset);
3137 reader& rdr = *
const_cast<reader*
>(
this);
3138 string qualified_name = die_qualified_name(rdr, die, where_offset);
3139 interned_string istr = env().intern(qualified_name);
3140 map[die_offset] = istr;
3160 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3162 return const_cast<reader*
>(
this)->
3163 get_die_qualified_name(die, where_offset);
3184 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3189 if (die == cur_tu_die())
3190 return env().intern(
"");
3193 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3196 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3197 die_istring_map_type::const_iterator i =
3198 map.find(die_offset);
3202 reader& rdr = *
const_cast<reader*
>(
this);
3203 string qualified_name;
3204 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3205 if ((tag == DW_TAG_structure_type
3206 || tag == DW_TAG_class_type
3207 || tag == DW_TAG_union_type)
3208 && die_is_anonymous(die))
3210 location l = die_location(*
this, die);
3211 qualified_name = l ? l.expand() :
"noloc";
3212 qualified_name =
"unnamed-at-" + qualified_name;
3216 die_qualified_type_name(rdr, die, where_offset);
3218 interned_string istr = env().intern(qualified_name);
3219 map[die_offset] = istr;
3243 get_die_pretty_type_representation(
const Dwarf_Die *die,
3244 size_t where_offset)
const
3248 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3251 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3252 die_istring_map_type::const_iterator i = map.find(die_offset);
3256 reader& rdr = *
const_cast<reader*
>(
this);
3257 string pretty_representation =
3258 die_pretty_print_type(rdr, die, where_offset);
3259 interned_string istr = env().intern(pretty_representation);
3260 map[die_offset] = istr;
3280 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3285 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3288 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3289 die_istring_map_type::const_iterator i = map.find(die_offset);
3293 reader& rdr = *
const_cast<reader*
>(
this);
3294 string pretty_representation =
3295 die_pretty_print(rdr, die, where_offset);
3296 interned_string istr = env().intern(pretty_representation);
3297 map[die_offset] = istr;
3321 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3324 lookup_artifact_from_die(die,
true);
3326 return fn->get_type();
3350 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3352 Dwarf_Die equiv_die;
3353 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3358 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3359 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3361 size_t die_offset = dwarf_dieoffset(&equiv_die);
3362 die_artefact_map_type::const_iterator i = m.find(die_offset);
3389 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3391 bool die_as_type =
false)
const
3395 ? type_die_artefact_maps().get_container(source)
3396 : decl_die_artefact_maps().get_container(source);
3398 die_artefact_map_type::const_iterator i = m.find(die_offset);
3441 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3456 if (!get_die_language(die, lang))
3467 die_source_dependant_container_set<die_artefact_map_type>&
3468 decl_die_artefact_maps()
3469 {
return decl_die_artefact_maps_;}
3476 const die_source_dependant_container_set<die_artefact_map_type>&
3477 decl_die_artefact_maps()
const
3478 {
return decl_die_artefact_maps_;}
3485 die_source_dependant_container_set<die_artefact_map_type>&
3486 type_die_artefact_maps()
3487 {
return type_die_artefact_maps_;}
3494 const die_source_dependant_container_set<die_artefact_map_type>&
3495 type_die_artefact_maps()
const
3496 {
return type_die_artefact_maps_;}
3504 per_tu_repr_to_fn_type_maps()
3505 {
return per_tu_repr_to_fn_type_maps_;}
3513 per_tu_repr_to_fn_type_maps()
const
3514 {
return per_tu_repr_to_fn_type_maps_;}
3524 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3527 if (!die_is_function_type(die))
3530 interned_string repr =
3531 get_die_pretty_type_representation(die, 0);
3534 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3545 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3547 if (!die_is_function_type(die))
3550 interned_string repr = die_name(die).empty() ?
3551 get_die_pretty_type_representation(die, 0)
3552 : get_die_pretty_representation(die, 0);
3555 istring_fn_type_map_type::const_iterator i =
3556 per_tu_repr_to_fn_type_maps().find(repr);
3558 if (i == per_tu_repr_to_fn_type_maps().end())
3575 Dwarf_Off die_offset,
3576 Dwarf_Off canonical_die_offset)
const
3578 canonical_dies[die_offset] = canonical_die_offset;}
3594 set_canonical_die_offset(Dwarf_Off die_offset,
3596 Dwarf_Off canonical_die_offset,
3597 bool die_as_type)
const
3601 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3602 get_container(source)
3603 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3604 get_container(source);
3606 set_canonical_die_offset(canonical_dies,
3608 canonical_die_offset);
3622 set_canonical_die_offset(
const Dwarf_Die *die,
3623 Dwarf_Off canonical_die_offset,
3624 bool die_as_type)
const
3626 const die_source source = get_die_source(die);
3628 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3630 set_canonical_die_offset(die_offset, source,
3631 canonical_die_offset,
3645 Dwarf_Off die_offset)
const
3647 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3648 if (it == canonical_dies.end())
3665 get_canonical_die_offset(Dwarf_Off die_offset,
3667 bool die_as_type)
const
3671 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3672 get_container(source)
3673 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3674 get_container(source);
3676 return get_canonical_die_offset(canonical_dies, die_offset);
3691 erase_canonical_die_offset(Dwarf_Off die_offset,
3693 bool die_as_type)
const
3697 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3698 get_container(source)
3699 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3700 get_container(source);
3702 return canonical_dies.erase(die_offset);
3715 associate_die_to_type(
const Dwarf_Die *die,
3716 type_base_sptr type,
3722 Dwarf_Die equiv_die;
3723 if (!get_or_compute_canonical_die(die, equiv_die, where,
3728 type_die_artefact_maps().get_container(*
this, &equiv_die);
3730 size_t die_offset = dwarf_dieoffset(&equiv_die);
3731 m[die_offset] = type;
3745 lookup_type_from_die(
const Dwarf_Die* die)
const
3748 lookup_artifact_from_die(die,
true);
3750 return fn->get_type();
3768 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3770 type_base_sptr result;
3772 type_die_artefact_maps().get_container(source);
3773 die_artefact_map_type::const_iterator i = m.find(die_offset);
3777 return fn->get_type();
3785 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3795 die_wip_function_types_map(source);
3796 die_function_type_map_type::const_iterator i = m.find(die_offset);
3815 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3830 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3832 case ALT_DEBUG_INFO_DIE_SOURCE:
3833 return alternate_die_wip_classes_map_;
3834 case TYPE_UNIT_DIE_SOURCE:
3835 return type_unit_die_wip_classes_map_;
3836 case NO_DEBUG_INFO_DIE_SOURCE:
3837 case NUMBER_OF_DIE_SOURCES:
3840 return die_wip_classes_map_;
3851 die_wip_function_types_map(
die_source source)
const
3852 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3862 die_wip_function_types_map(
die_source source)
3866 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3868 case ALT_DEBUG_INFO_DIE_SOURCE:
3869 return alternate_die_wip_function_types_map_;
3870 case TYPE_UNIT_DIE_SOURCE:
3871 return type_unit_die_wip_function_types_map_;
3872 case NO_DEBUG_INFO_DIE_SOURCE:
3873 case NUMBER_OF_DIE_SOURCES:
3876 return die_wip_function_types_map_;
3887 die_function_decl_with_no_symbol_map()
3888 {
return die_function_with_no_symbol_map_;}
3901 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3903 die_class_or_union_map_type::const_iterator i =
3904 die_wip_classes_map(source).find(offset);
3905 return (i != die_wip_classes_map(source).end());
3919 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3921 die_function_type_map_type::const_iterator i =
3922 die_wip_function_types_map(source).find(offset);
3923 return (i != die_wip_function_types_map(source).end());
3942 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3948 || dwarf_tag(die) != DW_TAG_member
3949 || !die_name(die).empty())
3955 if (die_is_anonymous_data_member(die))
3961 int64_t offset_in_bits = 0;
3962 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3966 loc = die_location(*
this, die);
3971 std::ostringstream o;
3972 o <<
"unnamed-dm-@-";
3974 o <<
"offset-" << offset_in_bits <<
"bits";
3976 o <<
"loc-" << loc.expand();
3989 declaration_only_classes()
const
3990 {
return decl_only_classes_map_;}
4000 declaration_only_classes()
4001 {
return decl_only_classes_map_;}
4009 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
4011 if (cou->get_is_declaration_only()
4012 && cou->get_definition_of_declaration() == 0
4017 && !cou->get_qualified_name().empty())
4019 string qn = cou->get_qualified_name();
4020 string_classes_or_unions_map::iterator record =
4021 declaration_only_classes().find(qn);
4022 if (record == declaration_only_classes().end())
4023 declaration_only_classes()[qn].push_back(cou);
4025 record->second.push_back(cou);
4037 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4039 if (cou->get_is_declaration_only())
4040 return ((declaration_only_classes().find(cou->get_qualified_name())
4041 != declaration_only_classes().end())
4042 || (declaration_only_classes().find(cou->get_name())
4043 != declaration_only_classes().end()));
4063 const environment& e = l->get_environment();
4066 e.priv_->allow_type_comparison_results_caching(
true);
4067 bool s0 = e.decl_only_class_equals_definition();
4068 e.decl_only_class_equals_definition(
true);
4069 bool equal = l == r;
4070 e.decl_only_class_equals_definition(s0);
4071 e.priv_->clear_type_comparison_results_cache();
4072 e.priv_->allow_type_comparison_results_caching(
false);
4079 resolve_declaration_only_classes()
4081 vector<string> resolved_classes;
4083 for (string_classes_or_unions_map::iterator i =
4084 declaration_only_classes().begin();
4085 i != declaration_only_classes().end();
4088 bool to_resolve =
false;
4089 for (classes_or_unions_type::iterator j = i->second.begin();
4090 j != i->second.end();
4092 if ((*j)->get_is_declaration_only()
4093 && ((*j)->get_definition_of_declaration() == 0))
4098 resolved_classes.push_back(i->first);
4143 map<string, class_or_union_sptr> per_tu_class_map;
4144 for (type_base_wptrs_type::const_iterator c = classes->begin();
4145 c != classes->end();
4152 if (klass->get_is_declaration_only())
4155 string tu_path = klass->get_translation_unit()->get_absolute_path();
4156 if (tu_path.empty())
4162 per_tu_class_map[tu_path] = klass;
4165 if (!per_tu_class_map.empty())
4171 for (classes_or_unions_type::iterator j = i->second.begin();
4172 j != i->second.end();
4175 if ((*j)->get_is_declaration_only()
4176 && ((*j)->get_definition_of_declaration() == 0))
4179 (*j)->get_translation_unit()->get_absolute_path();
4180 map<string, class_or_union_sptr>::const_iterator e =
4181 per_tu_class_map.find(tu_path);
4182 if (e != per_tu_class_map.end())
4183 (*j)->set_definition_of_declaration(e->second);
4184 else if (per_tu_class_map.size() == 1)
4185 (*j)->set_definition_of_declaration
4186 (per_tu_class_map.begin()->second);
4196 class_or_union_sptr>::const_iterator it;
4197 class_or_union_sptr first_class =
4198 per_tu_class_map.begin()->second;
4199 bool all_class_definitions_are_equal =
true;
4200 for (it = per_tu_class_map.begin();
4201 it != per_tu_class_map.end();
4204 if (it == per_tu_class_map.begin())
4208 if (!compare_before_canonicalisation(it->second,
4211 all_class_definitions_are_equal =
false;
4216 if (all_class_definitions_are_equal)
4217 (*j)->set_definition_of_declaration(first_class);
4221 resolved_classes.push_back(i->first);
4225 size_t num_decl_only_classes = declaration_only_classes().size(),
4226 num_resolved = resolved_classes.size();
4228 cerr <<
"resolved " << num_resolved
4229 <<
" class declarations out of "
4230 << num_decl_only_classes
4233 for (vector<string>::const_iterator i = resolved_classes.begin();
4234 i != resolved_classes.end();
4236 declaration_only_classes().erase(*i);
4238 if (show_stats() && !declaration_only_classes().empty())
4240 cerr <<
"Here are the "
4241 << num_decl_only_classes - num_resolved
4242 <<
" unresolved class declarations:\n";
4243 for (string_classes_or_unions_map::iterator i =
4244 declaration_only_classes().begin();
4245 i != declaration_only_classes().end();
4247 cerr <<
" " << i->first <<
"\n";
4259 declaration_only_enums()
const
4260 {
return decl_only_enums_map_;}
4270 declaration_only_enums()
4271 {
return decl_only_enums_map_;}
4281 if (enom->get_is_declaration_only()
4282 && enom->get_definition_of_declaration() == 0
4287 && !enom->get_qualified_name().empty())
4289 string qn = enom->get_qualified_name();
4290 string_enums_map::iterator record =
4291 declaration_only_enums().find(qn);
4292 if (record == declaration_only_enums().end())
4293 declaration_only_enums()[qn].push_back(enom);
4295 record->second.push_back(enom);
4309 if (enom->get_is_declaration_only())
4310 return (declaration_only_enums().find(enom->get_qualified_name())
4311 != declaration_only_enums().end());
4324 resolve_declaration_only_enums()
4326 vector<string> resolved_enums;
4328 for (string_enums_map::iterator i =
4329 declaration_only_enums().begin();
4330 i != declaration_only_enums().end();
4333 bool to_resolve =
false;
4334 for (enums_type::iterator j = i->second.begin();
4335 j != i->second.end();
4337 if ((*j)->get_is_declaration_only()
4338 && ((*j)->get_definition_of_declaration() == 0))
4343 resolved_enums.push_back(i->first);
4385 map<string, enum_type_decl_sptr> per_tu_enum_map;
4386 for (type_base_wptrs_type::const_iterator c = enums->begin();
4394 if (enom->get_is_declaration_only())
4397 string tu_path = enom->get_translation_unit()->get_absolute_path();
4398 if (tu_path.empty())
4404 per_tu_enum_map[tu_path] = enom;
4407 if (!per_tu_enum_map.empty())
4413 for (enums_type::iterator j = i->second.begin();
4414 j != i->second.end();
4417 if ((*j)->get_is_declaration_only()
4418 && ((*j)->get_definition_of_declaration() == 0))
4421 (*j)->get_translation_unit()->get_absolute_path();
4422 map<string, enum_type_decl_sptr>::const_iterator e =
4423 per_tu_enum_map.find(tu_path);
4424 if (e != per_tu_enum_map.end())
4425 (*j)->set_definition_of_declaration(e->second);
4426 else if (per_tu_enum_map.size() == 1)
4427 (*j)->set_definition_of_declaration
4428 (per_tu_enum_map.begin()->second);
4440 per_tu_enum_map.begin()->second;
4441 bool all_enum_definitions_are_equal =
true;
4442 for (it = per_tu_enum_map.begin();
4443 it != per_tu_enum_map.end();
4446 if (it == per_tu_enum_map.begin())
4450 if (!compare_before_canonicalisation(it->second,
4453 all_enum_definitions_are_equal =
false;
4458 if (all_enum_definitions_are_equal)
4459 (*j)->set_definition_of_declaration(first_enum);
4463 resolved_enums.push_back(i->first);
4467 size_t num_decl_only_enums = declaration_only_enums().size(),
4468 num_resolved = resolved_enums.size();
4470 cerr <<
"resolved " << num_resolved
4471 <<
" enum declarations out of "
4472 << num_decl_only_enums
4475 for (vector<string>::const_iterator i = resolved_enums.begin();
4476 i != resolved_enums.end();
4478 declaration_only_enums().erase(*i);
4480 if (show_stats() && !declaration_only_enums().empty())
4482 cerr <<
"Here are the "
4483 << num_decl_only_enums - num_resolved
4484 <<
" unresolved enum declarations:\n";
4485 for (string_enums_map::iterator i = declaration_only_enums().begin();
4486 i != declaration_only_enums().end();
4488 cerr <<
" " << i->first <<
"\n";
4504 corpus_sptr corp = corpus();
4508 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4510 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4515 if (f->get_symbol())
4535 fixup_functions_with_no_symbols()
4537 corpus_sptr corp = corpus();
4542 die_function_decl_with_no_symbol_map();
4545 cerr << fns_with_no_symbol.size()
4546 <<
" functions to fixup, potentially\n";
4548 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4549 i != fns_with_no_symbol.end();
4552 corp->lookup_function_symbol(i->second->get_linkage_name()))
4567 if (i->second->get_symbol()
4568 || symbol_already_belongs_to_a_function(sym))
4573 i->second->set_symbol(sym);
4576 cerr <<
"fixed up '"
4577 << i->second->get_pretty_representation()
4578 <<
"' with symbol '"
4579 << sym->get_id_string()
4583 fns_with_no_symbol.clear();
4593 const vector<type_base_sptr>&
4594 types_to_canonicalize()
const
4595 {
return types_to_canonicalize_;}
4599 clear_types_to_canonicalize()
4601 types_to_canonicalize_.clear();
4609 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4611 types_to_canonicalize_.push_back(t);
4621 canonicalize_types_scheduled()
4623 tools_utils::timer cn_timer;
4626 cerr <<
"DWARF Reader is going to canonicalize types";
4627 corpus_sptr c = corpus();
4629 cerr <<
" of corpus " << corpus()->get_path() <<
"\n";
4633 if (!types_to_canonicalize().empty())
4635 types_to_canonicalize().end(),
4636 [](
const vector<type_base_sptr>::const_iterator& i)
4642 cerr <<
"finished canonicalizing types";
4643 corpus_sptr c = corpus();
4645 cerr <<
" of corpus " << corpus()->get_path();
4646 cerr <<
": (" << cn_timer <<
")\n";
4663 add_late_canonicalized_types_stats(
size_t& canonicalized,
4664 size_t& missed)
const
4666 for (
auto t : types_to_canonicalize())
4668 if (t->get_canonical_type())
4678 perform_late_type_canonicalizing()
4680 canonicalize_types_scheduled();
4684 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4685 add_late_canonicalized_types_stats(num_canonicalized,
4687 total = num_canonicalized + num_missed;
4691 cerr <<
" # late canonicalized types: "
4692 << num_canonicalized;
4694 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4696 <<
" # missed canonicalization opportunities: "
4699 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4707 {
return die_tu_map_;}
4711 {
return die_tu_map_;}
4720 tu_die_imported_unit_points_map(
die_source source)
const
4721 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4730 tu_die_imported_unit_points_map(
die_source source)
4734 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4736 case ALT_DEBUG_INFO_DIE_SOURCE:
4737 return alt_tu_die_imported_unit_points_map_;
4738 case TYPE_UNIT_DIE_SOURCE:
4739 return type_units_tu_die_imported_unit_points_map_;
4740 case NO_DEBUG_INFO_DIE_SOURCE:
4741 case NUMBER_OF_DIE_SOURCES:
4745 return tu_die_imported_unit_points_map_;
4763 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4776 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4778 case ALT_DEBUG_INFO_DIE_SOURCE:
4779 return alternate_die_parent_map_;
4780 case TYPE_UNIT_DIE_SOURCE:
4781 return type_section_die_parent_map();
4782 case NO_DEBUG_INFO_DIE_SOURCE:
4783 case NUMBER_OF_DIE_SOURCES:
4786 return primary_die_parent_map_;
4790 type_section_die_parent_map()
const
4791 {
return type_section_die_parent_map_;}
4794 type_section_die_parent_map()
4795 {
return type_section_die_parent_map_;}
4801 cur_transl_unit()
const
4825 global_scope()
const
4826 {
return cur_transl_unit()->get_global_scope();}
4833 {
return nil_scope_;}
4837 {
return scope_stack_;}
4841 {
return scope_stack_;}
4846 if (scope_stack().empty())
4848 if (cur_transl_unit())
4851 return scope_stack().top();
4854 list<var_decl_sptr>&
4855 var_decls_to_re_add_to_tree()
4856 {
return var_decls_to_add_;}
4869 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
const
4871 if (!die || !die_is_decl(die))
4874 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4875 Dwarf_Addr decl_symbol_address = 0;
4877 if (die_is_variable_decl(die))
4879 if ((address_found = get_variable_address(die, decl_symbol_address)))
4880 symbol_is_exported =
4881 !!variable_symbol_is_exported(decl_symbol_address);
4883 else if (die_is_function_decl(die))
4885 if ((address_found = get_function_address(die, decl_symbol_address)))
4886 symbol_is_exported =
4887 !!function_symbol_is_exported(decl_symbol_address);
4891 result = symbol_is_exported;
4902 is_decl_die_with_undefined_symbol(
const Dwarf_Die *die)
const
4904 if (is_decl_die_with_exported_symbol(die))
4907 string name, linkage_name;
4908 die_name_and_linkage_name(die, name, linkage_name);
4909 if (linkage_name.empty())
4910 linkage_name = name;
4912 bool result =
false;
4913 if ((die_is_variable_decl(die)
4914 && symtab()->variable_symbol_is_undefined(linkage_name))
4916 (die_is_function_decl(die)
4917 && symtab()->function_symbol_is_undefined(linkage_name)))
4937 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4943 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4945 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4947 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4949 dwarf_elf_load_address));
4952 if (dwarf_is_splitted()
4953 && (dwarf_elf_load_address != elf_load_address))
4964 addr = addr - dwarf_elf_load_address + elf_load_address;
4990 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4995 Elf* elf = elf_handle();
4997 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4999 if (elf_header->e_type == ET_REL)
5012 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5037 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
5039 Elf* elf = elf_handle();
5041 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5043 if (elf_header->e_type == ET_REL)
5056 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5075 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5076 Dwarf_Addr& address)
const
5079 Dwarf_Addr end_addr;
5080 ptrdiff_t offset = 0;
5084 Dwarf_Addr addr = 0, fn_addr = 0;
5085 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5087 fn_addr = maybe_adjust_fn_sym_address(addr);
5088 if (function_symbol_is_exported(fn_addr))
5094 }
while (offset > 0);
5112 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5114 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5115 DW_AT_low_pc, address))
5121 if (!get_first_exported_fn_address_from_DW_AT_ranges
5122 (
const_cast<Dwarf_Die*
>(function_die),
5126 address = maybe_adjust_fn_sym_address(address);
5145 get_variable_address(
const Dwarf_Die* variable_die,
5146 Dwarf_Addr& address)
const
5148 bool is_tls_address =
false;
5149 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5150 address, is_tls_address))
5152 if (!is_tls_address)
5153 address = maybe_adjust_var_sym_address(address);
5160 corpus::exported_decls_builder*
5161 exported_decls_builder()
5162 {
return corpus()->get_exported_decls_builder().get();}
5170 load_all_types()
const
5171 {
return options().load_all_types;}
5179 load_all_types(
bool f)
5180 {options().load_all_types = f;}
5183 load_in_linux_kernel_mode()
const
5184 {
return options().load_in_linux_kernel_mode;}
5187 load_in_linux_kernel_mode(
bool f)
5188 {options().load_in_linux_kernel_mode = f;}
5200 load_undefined_interfaces()
const
5201 {
return options().load_undefined_interfaces;}
5211 leverage_dwarf_factorization()
const
5213 if (!leverage_dwarf_factorization_.has_value())
5215 if (options().leverage_dwarf_factorization
5216 && elf_helpers::find_section_by_name(elf_handle(),
5217 ".gnu_debugaltlink"))
5218 leverage_dwarf_factorization_ =
true;
5220 leverage_dwarf_factorization_ =
false;
5222 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5224 return *leverage_dwarf_factorization_;
5234 {
return options().show_stats;}
5244 {options().show_stats = f;}
5254 {
return options().do_log;}
5263 {options().do_log = f;}
5283 build_die_parent_relations_under(Dwarf_Die* die,
5293 if (dwarf_child(die, &child) != 0)
5298 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5299 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5301 Dwarf_Die imported_unit;
5302 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5313 && die_has_children(&imported_unit))
5315 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5316 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5317 imported_units.push_back
5318 (imported_unit_point(dwarf_dieoffset(&child),
5320 imported_unit_die_source));
5323 build_die_parent_relations_under(&child, source, imported_units);
5325 while (dwarf_siblingof(&child, &child) == 0);
5357 case translation_unit::LANG_UNKNOWN:
5358 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5359 case translation_unit::LANG_Mips_Assembler:
5386 build_die_parent_maps()
5388 bool we_do_have_to_build_die_parent_map =
false;
5389 uint8_t address_size = 0;
5390 size_t header_size = 0;
5395 for (Dwarf_Off offset = 0, next_offset = 0;
5396 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5397 offset, &next_offset, &header_size,
5398 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5399 offset = next_offset)
5401 Dwarf_Off die_offset = offset + header_size;
5403 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
5408 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5410 if (do_we_build_die_parent_maps(lang))
5411 we_do_have_to_build_die_parent_map =
true;
5414 if (!we_do_have_to_build_die_parent_map)
5419 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5420 for (Dwarf_Off offset = 0, next_offset = 0;
5421 (dwarf_next_unit(
const_cast<Dwarf*
>(alternate_dwarf_debug_info()),
5422 offset, &next_offset, &header_size,
5423 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5424 offset = next_offset)
5426 Dwarf_Off die_offset = offset + header_size;
5428 if (!dwarf_offdie(
const_cast<Dwarf*
>(alternate_dwarf_debug_info()),
5434 tu_die_imported_unit_points_map(source)[die_offset] =
5436 build_die_parent_relations_under(&cu, source, imported_units);
5441 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5444 for (Dwarf_Off offset = 0, next_offset = 0;
5445 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5446 offset, &next_offset, &header_size,
5447 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5448 offset = next_offset)
5450 Dwarf_Off die_offset = offset + header_size;
5452 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
5457 tu_die_imported_unit_points_map(source)[die_offset] =
5459 build_die_parent_relations_under(&cu, source, imported_units);
5464 source = TYPE_UNIT_DIE_SOURCE;
5467 uint64_t type_signature = 0;
5468 Dwarf_Off type_offset;
5469 for (Dwarf_Off offset = 0, next_offset = 0;
5470 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5471 offset, &next_offset, &header_size,
5472 NULL, NULL, &address_size, NULL,
5473 &type_signature, &type_offset) == 0);
5474 offset = next_offset)
5476 Dwarf_Off die_offset = offset + header_size;
5479 if (!dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_debug_info()),
5484 tu_die_imported_unit_points_map(source)[die_offset] =
5486 build_die_parent_relations_under(&cu, source, imported_units);
5501 struct offset_pairs_stack_type
5518 offset_pairs_stack_type(
const reader& rdr)
5544 offset_pair_vector_type::iterator i;
5546 for (i = vect_.begin();i < vect_.end(); ++i)
5550 if (i != vect_.end())
5569 if (set_.find(p) == set_.end())
5596 bool result =
false;
5601 offset_pair_vector_type::const_iterator i;
5602 for (i = vect_.begin(); i != vect_.end(); ++i)
5606 if (i == vect_.end())
5611 for (++i; i != vect_.end(); ++i)
5613 pairs.push_back(*i);
5633 for (
auto type_pair : dependant_types)
5634 dependant_types_[type_pair].push_back(p);
5645 get_pairs_that_depend_on(p, dependant_types);
5648 auto it = redundant_types_.find(p);
5649 if (it == redundant_types_.end())
5651 auto entry = std::make_pair(p, dependant_types);
5652 redundant_types_.insert(entry);
5655 it->second.insert(it->second.end(),
5656 dependant_types.begin(),
5657 dependant_types.end());
5661 record_dependant_types(p, dependant_types);
5672 auto i = redundant_types_.find(p);
5673 if (i != redundant_types_.end())
5686 auto i = dependant_types_.find(p);
5687 if (i == dependant_types_.end())
5705 bool erase_cached_results =
false)
5709 auto redundant_type = redundant_types_.find(p);
5710 if (redundant_type != redundant_types_.end())
5712 for (
auto dependant_type : redundant_type->second)
5716 auto dependant_types_it = dependant_types_.find(dependant_type);
5717 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5721 auto i = dependant_types_it->second.begin();
5722 for (; i!= dependant_types_it->second.end();++i)
5725 if (i != dependant_types_it->second.end())
5726 dependant_types_it->second.erase(i);
5731 if (dependant_types_it->second.empty())
5733 if (erase_cached_results)
5734 rdr_.die_comparison_results_.erase(dependant_type);
5735 dependant_types_.erase(dependant_types_it);
5739 if (erase_cached_results)
5740 rdr_.die_comparison_results_.erase(p);
5741 redundant_types_.erase(p);
5753 {erase_redundant_type_pair_entry(p,
true);}
5766 get_dependant_types(p, dependant_types,
true);
5767 for (
auto dependant_type : dependant_types)
5771 if (rdr_.propagated_types_.find(dependant_type)
5772 != rdr_.propagated_types_.end())
5774 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5775 dependant_type.first.source_,
5777 rdr_.propagated_types_.erase(dependant_type);
5778 rdr_.cancelled_propagation_count_++;
5782 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5783 if (comp_result_it != rdr_.die_comparison_results_.end())
5784 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5788 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5789 if (comp_result_it != rdr_.die_comparison_results_.end())
5796 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5797 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5798 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5801 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5803 rdr_.erase_canonical_die_offset(p.first.offset_,
5806 rdr_.propagated_types_.erase(p);
5807 rdr_.cancelled_propagation_count_++;
5826 bool transitive_closure =
false)
5828 auto i = redundant_types_.find(p);
5829 if (i != redundant_types_.end())
5831 for (
auto dependant_type : i->second)
5832 if (result.find(dependant_type) == result.end())
5834 result.insert(dependant_type);
5835 if (transitive_closure)
5836 get_dependant_types(p, result,
true);
5845 build_ir_node_from_die(reader& rdr,
5848 bool called_from_public_decl,
5849 size_t where_offset,
5850 bool is_declaration_only =
true,
5851 bool is_required_decl_spec =
false);
5854 build_ir_node_from_die(reader& rdr,
5856 bool called_from_public_decl,
5857 size_t where_offset);
5859 static decl_base_sptr
5860 build_ir_node_for_void_type(reader& rdr);
5863 build_ir_node_for_void_pointer_type(reader& rdr);
5866 add_or_update_class_type(reader& rdr,
5871 bool called_from_public_decl,
5872 size_t where_offset,
5873 bool is_declaration_only);
5875 static union_decl_sptr
5876 add_or_update_union_type(reader& rdr,
5879 union_decl_sptr union_type,
5880 bool called_from_public_decl,
5881 size_t where_offset,
5882 bool is_declaration_only);
5884 static decl_base_sptr
5885 build_ir_node_for_void_type(reader& rdr);
5887 static decl_base_sptr
5888 build_ir_node_for_variadic_parameter_type(reader &rdr);
5891 build_function_decl(reader& rdr,
5893 size_t where_offset,
5897 function_is_suppressed(
const reader& rdr,
5898 const scope_decl* scope,
5899 Dwarf_Die *function_die,
5900 bool is_declaration_only);
5903 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5906 size_t where_offset,
5907 bool is_declaration_only,
5911 build_var_decl(reader& rdr,
5913 size_t where_offset,
5917 build_or_get_var_decl_if_not_suppressed(reader& rdr,
5920 size_t where_offset,
5921 bool is_declaration_only,
5923 bool is_required_decl_spec =
false);
5925 variable_is_suppressed(
const reader& rdr,
5926 const scope_decl* scope,
5927 Dwarf_Die *variable_die,
5928 bool is_declaration_only,
5929 bool is_required_decl_spec =
false);
5932 finish_member_function_reading(Dwarf_Die* die,
5934 const class_or_union_sptr klass,
5943 die_is_anonymous(
const Dwarf_Die* die)
5945 Dwarf_Attribute attr;
5946 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
5960 die_is_anonymous_data_member(
const Dwarf_Die* die)
5963 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
5964 || !die_name(die).empty())
5968 if (!die_die_attribute(die, DW_AT_type, type_die))
5971 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5972 && dwarf_tag(&type_die) != DW_TAG_union_type)
5989 die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5994 Dwarf_Attribute attr;
5995 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5998 const char* str = dwarf_formstring(&attr);
5999 return str ? str :
"";
6013 die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6018 Dwarf_Attribute attr;
6019 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6022 const char* str = dwarf_formstring(&attr);
6042 die_unsigned_constant_attribute(
const Dwarf_Die* die,
6049 Dwarf_Attribute attr;
6050 Dwarf_Word result = 0;
6051 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6052 || dwarf_formudata(&attr, &result))
6072 die_signed_constant_attribute(
const Dwarf_Die *die,
6079 Dwarf_Attribute attr;
6080 Dwarf_Sword result = 0;
6081 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6082 || dwarf_formsdata(&attr, &result))
6108 die_constant_attribute(
const Dwarf_Die *die,
6111 array_type_def::subrange_type::bound_value &value)
6116 if (!die_unsigned_constant_attribute(die, attr_name, l))
6118 value.set_unsigned(l);
6123 if (!die_signed_constant_attribute(die, attr_name, l))
6125 value.set_signed(l);
6140 form_is_DW_FORM_strx(
unsigned form)
6144 #if defined HAVE_DW_FORM_strx1 \
6145 && defined HAVE_DW_FORM_strx2 \
6146 && defined HAVE_DW_FORM_strx3 \
6147 && defined HAVE_DW_FORM_strx4
6148 if (form == DW_FORM_strx1
6149 || form == DW_FORM_strx2
6150 || form == DW_FORM_strx3
6151 ||form == DW_FORM_strx4)
6168 form_is_DW_FORM_line_strp(
unsigned form)
6172 #if defined HAVE_DW_FORM_line_strp
6173 if (form == DW_FORM_line_strp)
6200 die_flag_attribute(
const Dwarf_Die* die,
6203 bool recursively =
true)
6205 Dwarf_Attribute attr;
6207 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6208 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6212 if (dwarf_formflag(&attr, &f))
6226 die_linkage_name(
const Dwarf_Die* die)
6231 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6232 if (linkage_name.empty())
6233 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6234 return linkage_name;
6248 die_decl_file_attribute(
const Dwarf_Die* die)
6253 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6255 return str ? str :
"";
6276 die_die_attribute(
const Dwarf_Die* die,
6281 Dwarf_Attribute attr;
6283 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6284 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6287 return dwarf_formref_die(&attr, &result);
6312 die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6314 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6315 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6317 while (die_die_attribute(&origin_die,
6318 DW_AT_specification,
6320 || die_die_attribute(&origin_die,
6321 DW_AT_abstract_origin,
6359 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6361 Dwarf_Die& referenced_subrange)
6363 bool result =
false;
6365 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6368 Dwarf_Die referenced_die;
6369 if (die_die_attribute(die, attr_name, referenced_die))
6371 unsigned tag = dwarf_tag(&referenced_die);
6372 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6375 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6377 tag = dwarf_tag(&type_die);
6378 if (tag == DW_TAG_subrange_type)
6380 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6416 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6418 array_type_def::subrange_type::bound_value& v,
6421 bool result =
false;
6423 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6426 Dwarf_Die subrange_die;
6427 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6430 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6448 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6450 Dwarf_Attribute attr;
6451 if (!dwarf_attr_integrate(die, attr_name, &attr))
6453 return dwarf_formaddr(&attr, &result) == 0;
6464 die_location(
const reader& rdr,
const Dwarf_Die* die)
6469 string file = die_decl_file_attribute(die);
6471 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6473 if (!file.empty() && line != 0)
6476 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6488 die_name(
const Dwarf_Die* die)
6490 string name = die_string_attribute(die, DW_AT_name);
6506 die_loc_and_name(
const reader& rdr,
6510 string& linkage_name)
6512 loc = die_location(rdr, die);
6513 name = die_name(die);
6514 linkage_name = die_linkage_name(die);
6525 die_name_and_linkage_name(
const Dwarf_Die* die,
6527 string& linkage_name)
6529 name = die_name(die);
6530 linkage_name = die_linkage_name(die);
6543 die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6548 uint64_t byte_size = 0, bit_size = 0;
6550 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6552 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6556 bit_size = byte_size * 8;
6579 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6586 case private_access:
6587 result = private_access;
6590 case protected_access:
6591 result = protected_access;
6595 result = public_access;
6614 die_is_public_decl(
const Dwarf_Die* die)
6618 bool is_public =
false;
6624 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6625 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6626 die_flag_attribute(die, DW_AT_external, is_public);
6627 else if (tag == DW_TAG_namespace)
6629 string name = die_name(die);
6630 is_public = !name.empty();
6644 die_is_effectively_public_decl(
const reader& rdr,
6645 const Dwarf_Die* die)
6647 if (die_is_public_decl(die))
6650 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6651 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6654 Dwarf_Die parent_die;
6655 size_t where_offset = 0;
6656 if (!get_parent_die(rdr, die, parent_die, where_offset))
6659 tag = dwarf_tag(&parent_die);
6660 if (tag == DW_TAG_compile_unit
6661 || tag == DW_TAG_partial_unit
6662 || tag == DW_TAG_type_unit)
6666 if (tag == DW_TAG_namespace)
6668 string name = die_name(&parent_die);
6687 die_is_declaration_only(Dwarf_Die* die)
6689 bool is_declaration =
false;
6690 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6691 if (is_declaration && !die_has_size_attribute(die))
6702 die_is_function_decl(
const Dwarf_Die *die)
6707 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6708 if (tag == DW_TAG_subprogram)
6719 die_is_variable_decl(
const Dwarf_Die *die)
6724 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6725 if (tag == DW_TAG_variable)
6736 die_has_size_attribute(
const Dwarf_Die *die)
6739 if (die_size_in_bits(die, s))
6750 die_has_no_child(
const Dwarf_Die *die)
6756 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6769 die_is_declaration_only(
const Dwarf_Die* die)
6770 {
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6778 die_is_artificial(Dwarf_Die* die)
6781 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6788 is_type_tag(
unsigned tag)
6790 bool result =
false;
6794 case DW_TAG_array_type:
6795 case DW_TAG_class_type:
6796 case DW_TAG_enumeration_type:
6797 case DW_TAG_pointer_type:
6798 case DW_TAG_reference_type:
6799 case DW_TAG_string_type:
6800 case DW_TAG_structure_type:
6801 case DW_TAG_subroutine_type:
6802 case DW_TAG_typedef:
6803 case DW_TAG_union_type:
6804 case DW_TAG_ptr_to_member_type:
6805 case DW_TAG_set_type:
6806 case DW_TAG_subrange_type:
6807 case DW_TAG_base_type:
6808 case DW_TAG_const_type:
6809 case DW_TAG_file_type:
6810 case DW_TAG_packed_type:
6811 case DW_TAG_thrown_type:
6812 case DW_TAG_volatile_type:
6813 case DW_TAG_restrict_type:
6814 case DW_TAG_interface_type:
6815 case DW_TAG_unspecified_type:
6816 case DW_TAG_shared_type:
6817 case DW_TAG_rvalue_reference_type:
6818 case DW_TAG_coarray_type:
6819 case DW_TAG_atomic_type:
6820 case DW_TAG_immutable_type:
6843 is_canon_type_to_be_propagated_tag(
unsigned tag)
6845 bool result =
false;
6849 case DW_TAG_class_type:
6850 case DW_TAG_structure_type:
6851 case DW_TAG_union_type:
6852 case DW_TAG_subroutine_type:
6853 case DW_TAG_subprogram:
6874 type_comparison_result_to_be_cached(
unsigned tag)
6879 case DW_TAG_class_type:
6880 case DW_TAG_structure_type:
6881 case DW_TAG_union_type:
6882 case DW_TAG_subroutine_type:
6883 case DW_TAG_subprogram:
6904 maybe_cache_type_comparison_result(
const reader& rdr,
6909 if (!type_comparison_result_to_be_cached(tag)
6910 || (result != COMPARISON_RESULT_EQUAL
6911 && result != COMPARISON_RESULT_DIFFERENT))
6914 rdr.die_comparison_results_[p] = result;
6934 get_cached_type_comparison_result(
const reader& rdr,
6938 auto i = rdr.die_comparison_results_.find(p);
6939 if (i != rdr.die_comparison_results_.end())
6962 maybe_get_cached_type_comparison_result(
const reader& rdr,
6967 if (type_comparison_result_to_be_cached(tag))
6972 if (get_cached_type_comparison_result(rdr, p, result))
6984 is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
6986 bool result =
false;
6987 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6989 if (!is_type_tag(tag))
6994 case DW_TAG_class_type:
6995 case DW_TAG_structure_type:
6996 case DW_TAG_union_type:
6997 result = !die_is_declaration_only(die);
7000 case DW_TAG_subroutine_type:
7001 case DW_TAG_subprogram:
7002 case DW_TAG_array_type:
7018 is_decl_tag(
unsigned tag)
7022 case DW_TAG_formal_parameter:
7023 case DW_TAG_imported_declaration:
7025 case DW_TAG_unspecified_parameters:
7026 case DW_TAG_subprogram:
7027 case DW_TAG_variable:
7028 case DW_TAG_namespace:
7029 case DW_TAG_GNU_template_template_param:
7030 case DW_TAG_GNU_template_parameter_pack:
7031 case DW_TAG_GNU_formal_parameter_pack:
7043 die_is_type(
const Dwarf_Die* die)
7047 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7056 die_is_decl(
const Dwarf_Die* die)
7060 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7069 die_is_namespace(
const Dwarf_Die* die)
7073 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
7082 die_is_unspecified(Dwarf_Die* die)
7086 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7095 die_is_void_type(Dwarf_Die* die)
7097 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7100 string name = die_name(die);
7113 die_is_pointer_type(
const Dwarf_Die* die)
7118 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7119 if (tag == DW_TAG_pointer_type)
7133 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7135 if (!die_is_pointer_array_or_reference_type(die)
7136 && !die_is_qualified_type(die))
7139 Dwarf_Die underlying_type_die;
7140 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7143 if (!die_is_class_type(&underlying_type_die))
7146 string name = die_name(&underlying_type_die);
7148 return name.empty();
7157 die_is_reference_type(
const Dwarf_Die* die)
7162 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7163 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7175 die_is_array_type(
const Dwarf_Die* die)
7180 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7181 if (tag == DW_TAG_array_type)
7193 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7194 {
return (die_is_pointer_type(die)
7195 || die_is_reference_type(die)
7196 || die_is_array_type(die));}
7204 die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7205 {
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7214 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7215 {
return (die_is_pointer_array_or_reference_type(die)
7216 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7224 die_is_class_type(
const Dwarf_Die* die)
7226 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7228 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7240 die_is_qualified_type(
const Dwarf_Die* die)
7242 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7243 if (tag == DW_TAG_const_type
7244 || tag == DW_TAG_volatile_type
7245 || tag == DW_TAG_restrict_type)
7257 die_is_function_type(
const Dwarf_Die *die)
7259 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7260 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7278 die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7283 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7295 die_has_children(
const Dwarf_Die* die)
7301 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7321 die_this_pointer_from_object_pointer(Dwarf_Die* die,
7322 Dwarf_Die& this_pointer_die)
7325 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7327 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7342 die_this_pointer_is_const(Dwarf_Die* die)
7346 if (dwarf_tag(die) == DW_TAG_pointer_type)
7348 Dwarf_Die pointed_to_type_die;
7349 if (die_die_attribute(die, DW_AT_type, pointed_to_type_die))
7350 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7366 die_object_pointer_is_for_const_method(Dwarf_Die* die)
7369 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7371 Dwarf_Die this_pointer_die;
7372 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7373 if (die_this_pointer_is_const(&this_pointer_die))
7395 die_is_at_class_scope(
const reader& rdr,
7396 const Dwarf_Die* die,
7397 size_t where_offset,
7398 Dwarf_Die& class_scope_die)
7400 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7403 int tag = dwarf_tag(&class_scope_die);
7405 return (tag == DW_TAG_structure_type
7406 || tag == DW_TAG_class_type
7407 || tag == DW_TAG_union_type);
7420 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7425 int tag = dwarf_tag(die);
7427 if (tag == DW_TAG_const_type
7428 || tag == DW_TAG_volatile_type
7429 || tag == DW_TAG_restrict_type
7430 || tag == DW_TAG_pointer_type
7431 || tag == DW_TAG_reference_type
7432 || tag == DW_TAG_rvalue_reference_type)
7434 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7440 memcpy(&peeled_die, die,
sizeof(peeled_die));
7442 while (tag == DW_TAG_const_type
7443 || tag == DW_TAG_volatile_type
7444 || tag == DW_TAG_restrict_type
7445 || tag == DW_TAG_pointer_type
7446 || tag == DW_TAG_reference_type
7447 || tag == DW_TAG_rvalue_reference_type)
7449 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7451 tag = dwarf_tag(&peeled_die);
7466 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7471 memcpy(&peeled_die, die,
sizeof(peeled_die));
7473 int tag = dwarf_tag(&peeled_die);
7475 bool result =
false;
7476 while (tag == DW_TAG_const_type
7477 || tag == DW_TAG_volatile_type
7478 || tag == DW_TAG_restrict_type)
7480 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7482 tag = dwarf_tag(&peeled_die);
7498 die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7503 int tag = dwarf_tag(die);
7505 memcpy(&peeled_die, die,
sizeof(peeled_die));
7507 if (tag == DW_TAG_typedef)
7509 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7515 while (tag == DW_TAG_typedef)
7517 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7519 tag = dwarf_tag(&peeled_die);
7535 die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7540 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7542 if (tag == DW_TAG_pointer_type
7543 || tag == DW_TAG_reference_type
7544 || tag == DW_TAG_rvalue_reference_type
7545 || tag == DW_TAG_typedef)
7547 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7553 while (tag == DW_TAG_pointer_type
7554 || tag == DW_TAG_reference_type
7555 || tag == DW_TAG_rvalue_reference_type
7556 || tag == DW_TAG_typedef)
7558 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7560 tag = dwarf_tag(&peeled_die);
7588 die_function_type_is_method_type(
const reader& rdr,
7589 const Dwarf_Die *die,
7590 size_t where_offset,
7591 Dwarf_Die& object_pointer_die,
7592 Dwarf_Die& class_die,
7598 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7599 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7601 bool has_object_pointer =
false;
7603 if (tag == DW_TAG_subprogram)
7605 Dwarf_Die spec_or_origin_die;
7606 if (die_die_attribute(die, DW_AT_specification,
7608 || die_die_attribute(die, DW_AT_abstract_origin,
7609 spec_or_origin_die))
7611 if (die_has_object_pointer(&spec_or_origin_die,
7612 object_pointer_die))
7613 has_object_pointer =
true;
7616 if (die_is_at_class_scope(rdr, &spec_or_origin_die,
7617 where_offset, class_die))
7625 if (die_has_object_pointer(die, object_pointer_die))
7626 has_object_pointer =
true;
7629 if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7638 if (die_has_object_pointer(die, object_pointer_die))
7639 has_object_pointer =
true;
7650 Dwarf_Die this_type_die;
7651 if (!die_die_attribute(&object_pointer_die, DW_AT_type, this_type_die))
7656 if (!die_peel_qual_ptr(&this_type_die, class_die))
7661 die_peel_typedef(&class_die, class_die);
7669 VIRTUALITY_NOT_VIRTUAL,
7671 VIRTUALITY_PURE_VIRTUAL
7684 die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7690 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7692 if (v == DW_VIRTUALITY_virtual)
7693 virt = VIRTUALITY_VIRTUAL;
7694 else if (v == DW_VIRTUALITY_pure_virtual)
7695 virt = VIRTUALITY_PURE_VIRTUAL;
7697 virt = VIRTUALITY_NOT_VIRTUAL;
7709 die_is_virtual(
const Dwarf_Die* die)
7712 if (!die_virtuality(die, v))
7715 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7725 die_is_declared_inline(Dwarf_Die* die)
7727 uint64_t inline_value = 0;
7728 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7730 return (inline_value == DW_INL_declared_inlined
7731 || inline_value == DW_INL_declared_not_inlined);
7746 slowly_compare_strings(
const Dwarf_Die *l,
7750 const char *l_str = die_char_str_attribute(l, attr_name),
7751 *r_str = die_char_str_attribute(r, attr_name);
7752 if (!l_str && !r_str)
7754 return l_str && r_str && !strcmp(l_str, r_str);
7780 compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
7784 Dwarf_Attribute l_attr, r_attr;
7785 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
7786 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
7790 || l_attr.form == DW_FORM_string
7791 || l_attr.form == DW_FORM_GNU_strp_alt
7792 || form_is_DW_FORM_strx(l_attr.form)
7793 || form_is_DW_FORM_line_strp(l_attr.form));
7796 || r_attr.form == DW_FORM_string
7797 || r_attr.form == DW_FORM_GNU_strp_alt
7798 || form_is_DW_FORM_strx(r_attr.form)
7799 || form_is_DW_FORM_line_strp(r_attr.form));
7801 if ((l_attr.form == DW_FORM_strp
7802 && r_attr.form == DW_FORM_strp)
7803 || (l_attr.form == DW_FORM_GNU_strp_alt
7804 && r_attr.form == DW_FORM_GNU_strp_alt)
7805 || (form_is_DW_FORM_strx(l_attr.form)
7806 && form_is_DW_FORM_strx(r_attr.form))
7807 || (form_is_DW_FORM_line_strp(l_attr.form)
7808 && form_is_DW_FORM_line_strp(r_attr.form)))
7815 if (l_attr.valp == r_attr.valp)
7817 #if WITH_DEBUG_TYPE_CANONICALIZATION
7818 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
7829 result = slowly_compare_strings(l, r, attr_name);
7847 compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
7849 Dwarf_Die l_cu, r_cu;
7850 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
7851 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
7855 compare_dies_string_attribute_value(&l_cu, &r_cu,
7858 if (compared && result)
7860 Dwarf_Die peeled_l, peeled_r;
7861 if (die_is_pointer_reference_or_typedef_type(l)
7862 && die_is_pointer_reference_or_typedef_type(r)
7863 && die_peel_pointer_and_typedef(l, peeled_l)
7864 && die_peel_pointer_and_typedef(r, peeled_r))
7866 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
7867 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
7870 compare_dies_string_attribute_value(&l_cu, &r_cu,
7901 die_location_expr(
const Dwarf_Die* die,
7909 Dwarf_Attribute attr;
7910 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
7914 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
7949 op_pushes_constant_value(Dwarf_Op* ops,
7953 dwarf_expr_eval_context& ctxt)
7957 Dwarf_Op& op = ops[index];
7963 value = ops[index].number;
7976 value = ops[index].number;
8080 expr_result r(value);
8083 next_index = index + 1;
8113 op_pushes_non_constant_value(Dwarf_Op* ops,
8117 dwarf_expr_eval_context& ctxt)
8120 Dwarf_Op& op = ops[index];
8156 next_index = index + 1;
8191 next_index = index + 1;
8195 next_index = index + 2;
8199 next_index = index + 1;
8203 next_index = index + 1;
8206 case DW_OP_GNU_variable_value:
8207 next_index = index + 1;
8214 expr_result r(
false);
8243 op_manipulates_stack(Dwarf_Op* expr,
8247 dwarf_expr_eval_context& ctxt)
8249 Dwarf_Op& op = expr[index];
8255 v = ctxt.stack.front();
8260 v = ctxt.stack.front();
8279 ctxt.stack.erase(ctxt.stack.begin() + 1);
8286 ctxt.stack.erase(ctxt.stack.begin() + 2);
8291 case DW_OP_deref_size:
8299 case DW_OP_xderef_size:
8307 case DW_OP_push_object_address:
8312 case DW_OP_form_tls_address:
8313 case DW_OP_GNU_push_tls_address:
8316 if (op.atom == DW_OP_form_tls_address)
8321 case DW_OP_call_frame_cfa:
8333 if (op.atom == DW_OP_form_tls_address
8334 || op.atom == DW_OP_GNU_push_tls_address)
8335 ctxt.set_tls_address(
true);
8337 ctxt.set_tls_address(
false);
8339 next_index = index + 1;
8367 op_is_arith_logic(Dwarf_Op* expr,
8371 dwarf_expr_eval_context& ctxt)
8375 Dwarf_Op& op = expr[index];
8376 expr_result val1, val2;
8377 bool result =
false;
8393 ctxt.push(val1 & val2);
8400 if (!val1.is_const())
8402 ctxt.push(val2 / val1);
8410 ctxt.push(val2 - val1);
8418 ctxt.push(val2 % val1);
8426 ctxt.push(val2 * val1);
8448 ctxt.push(val1 | val2);
8456 ctxt.push(val2 + val1);
8460 case DW_OP_plus_uconst:
8472 ctxt.push(val2 << val1);
8481 ctxt.push(val2 >> val1);
8489 ctxt.push(val2 ^ val1);
8499 if (ctxt.stack.front().is_const())
8500 ctxt.accum = ctxt.stack.front();
8502 next_index = index + 1;
8530 op_is_control_flow(Dwarf_Op* expr,
8534 dwarf_expr_eval_context& ctxt)
8538 Dwarf_Op& op = expr[index];
8539 expr_result val1, val2;
8553 if (op.atom == DW_OP_eq)
8554 value = val2 == val1;
8555 else if (op.atom == DW_OP_ge)
8556 value = val2 >= val1;
8557 else if (op.atom == DW_OP_gt)
8558 value = val2 > val1;
8559 else if (op.atom == DW_OP_le)
8560 value = val2 <= val1;
8561 else if (op.atom == DW_OP_lt)
8562 value = val2 < val1;
8563 else if (op.atom == DW_OP_ne)
8564 value = val2 != val1;
8566 val1 = value ? 1 : 0;
8573 index += op.number - 1;
8578 if (val1.const_value() != 0)
8579 index += val1.const_value() - 1;
8584 case DW_OP_call_ref:
8592 if (ctxt.stack.front().is_const())
8593 ctxt.accum = ctxt.stack.front();
8595 next_index = index + 1;
8616 eval_quickly(Dwarf_Op* expr,
8620 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8622 value = expr[0].number;
8649 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8652 bool& is_tls_address,
8653 dwarf_expr_eval_context &eval_ctxt)
8659 size_t index = 0, next_index = 0;
8662 if (op_is_arith_logic(expr, expr_len, index,
8663 next_index, eval_ctxt)
8664 || op_pushes_constant_value(expr, expr_len, index,
8665 next_index, eval_ctxt)
8666 || op_manipulates_stack(expr, expr_len, index,
8667 next_index, eval_ctxt)
8668 || op_pushes_non_constant_value(expr, expr_len, index,
8669 next_index, eval_ctxt)
8670 || op_is_control_flow(expr, expr_len, index,
8671 next_index, eval_ctxt))
8674 next_index = index + 1;
8678 }
while (index < expr_len);
8680 is_tls_address = eval_ctxt.set_tls_address();
8681 if (eval_ctxt.accum.is_const())
8683 value = eval_ctxt.accum;
8703 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8706 bool& is_tls_address)
8708 dwarf_expr_eval_context eval_ctxt;
8709 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8710 is_tls_address, eval_ctxt);
8902 read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
8907 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
8920 uint64_t containing_anonymous_object_size = 0;
8921 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
8922 containing_anonymous_object_size));
8923 containing_anonymous_object_size *= 8;
8925 uint64_t bitfield_size = 0;
8926 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
8937 offset = containing_anonymous_object_size - off - bitfield_size;
8953 die_constant_data_member_location(
const Dwarf_Die *die,
8959 Dwarf_Attribute attr;
8960 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
8961 DW_AT_data_member_location,
8966 if (dwarf_formudata(&attr, &val) != 0)
9022 die_member_offset(
const reader& rdr,
9023 const Dwarf_Die* die,
9026 Dwarf_Op* expr = NULL;
9027 size_t expr_len = 0;
9028 uint64_t bit_offset = 0;
9032 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
9034 offset = bit_offset;
9046 if (!die_constant_data_member_location(die, offset))
9051 if (!die_location_expr(die, DW_AT_data_member_location,
9058 if (!eval_quickly(expr, expr_len, offset))
9060 bool is_tls_address =
false;
9061 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
9062 offset, is_tls_address,
9063 rdr.dwarf_expr_eval_ctxt()))
9081 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9082 offset += bit_offset;
9099 die_location_address(Dwarf_Die* die,
9100 Dwarf_Addr& address,
9101 bool& is_tls_address)
9103 Dwarf_Op* expr = NULL;
9104 size_t expr_len = 0;
9106 is_tls_address =
false;
9111 Dwarf_Attribute attr;
9112 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
9115 if (dwarf_getlocation(&attr, &expr, &expr_len))
9122 Dwarf_Attribute result;
9123 if (!dwarf_getlocation_attr(&attr, expr, &result))
9125 return !dwarf_formaddr(&result, &address);
9128 address = expr->number;
9143 die_virtual_function_index(Dwarf_Die* die,
9149 Dwarf_Op* expr = NULL;
9150 size_t expr_len = 0;
9151 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9156 bool is_tls_addr =
false;
9157 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9175 int tag = dwarf_tag(die);
9177 if (tag == DW_TAG_class_type
9178 || tag == DW_TAG_structure_type
9179 || tag == DW_TAG_union_type
9180 || tag == DW_TAG_enumeration_type)
9181 return die_is_anonymous(die);
9203 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9206 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9208 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9210 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9212 else if (tag == DW_TAG_union_type)
9214 else if (tag == DW_TAG_enumeration_type)
9233 build_internal_anonymous_die_name(
const string &
base_name,
9234 size_t anonymous_type_index)
9237 if (anonymous_type_index && !
base_name.empty())
9239 std::ostringstream o;
9259 get_internal_anonymous_die_name(Dwarf_Die *die,
9260 size_t anonymous_type_index)
9262 string name = get_internal_anonymous_die_prefix_name(die);
9263 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9285 die_qualified_type_name(
const reader& rdr,
9286 const Dwarf_Die* die,
9287 size_t where_offset)
9292 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9293 if (tag == DW_TAG_compile_unit
9294 || tag == DW_TAG_partial_unit
9295 || tag == DW_TAG_type_unit)
9298 string name = die_name(die);
9300 Dwarf_Die scope_die;
9301 if (!get_scope_die(rdr, die, where_offset, scope_die))
9304 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9305 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9306 string separator = colon_colon ?
"::" :
".";
9312 case DW_TAG_unspecified_type:
9315 case DW_TAG_base_type:
9325 case DW_TAG_typedef:
9326 case DW_TAG_enumeration_type:
9327 case DW_TAG_structure_type:
9328 case DW_TAG_class_type:
9329 case DW_TAG_union_type:
9337 name = get_internal_anonymous_die_prefix_name(die);
9340 repr = parent_name.empty() ? name : parent_name + separator + name;
9344 case DW_TAG_const_type:
9345 case DW_TAG_volatile_type:
9346 case DW_TAG_restrict_type:
9348 Dwarf_Die underlying_type_die;
9349 bool has_underlying_type_die =
9350 die_die_attribute(die, DW_AT_type, underlying_type_die);
9352 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9355 if (tag == DW_TAG_const_type)
9357 if (has_underlying_type_die
9358 && die_is_reference_type(&underlying_type_die))
9368 else if (!has_underlying_type_die
9369 || die_is_void_type(&underlying_type_die))
9377 else if (tag == DW_TAG_volatile_type)
9379 else if (tag == DW_TAG_restrict_type)
9384 string underlying_type_repr;
9385 if (has_underlying_type_die)
9386 underlying_type_repr =
9387 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9389 underlying_type_repr =
"void";
9391 if (underlying_type_repr.empty())
9395 if (has_underlying_type_die)
9398 die_peel_qualified(&underlying_type_die, peeled);
9399 if (die_is_pointer_or_reference_type(&peeled))
9400 repr = underlying_type_repr +
" " + repr;
9402 repr +=
" " + underlying_type_repr;
9405 repr +=
" " + underlying_type_repr;
9410 case DW_TAG_pointer_type:
9411 case DW_TAG_reference_type:
9412 case DW_TAG_rvalue_reference_type:
9414 Dwarf_Die pointed_to_type_die;
9415 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9417 if (tag == DW_TAG_pointer_type)
9422 if (die_is_unspecified(&pointed_to_type_die))
9425 string pointed_type_repr =
9426 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9428 repr = pointed_type_repr;
9432 if (tag == DW_TAG_pointer_type)
9434 else if (tag == DW_TAG_reference_type)
9436 else if (tag == DW_TAG_rvalue_reference_type)
9443 case DW_TAG_subrange_type:
9456 build_subrange_type(
const_cast<reader&
>(rdr),
9459 repr += s->as_string();
9463 case DW_TAG_array_type:
9465 Dwarf_Die element_type_die;
9466 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9468 string element_type_name =
9469 die_qualified_type_name(rdr, &element_type_die, where_offset);
9470 if (element_type_name.empty())
9474 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9475 die, subranges, where_offset,
9478 repr = element_type_name;
9479 repr += array_type_def::subrange_type::vector_as_string(subranges);
9483 case DW_TAG_subroutine_type:
9484 case DW_TAG_subprogram:
9486 string return_type_name;
9488 vector<string> parm_names;
9489 bool is_const =
false;
9490 bool is_static =
false;
9492 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9494 return_type_name, class_name,
9495 parm_names, is_const,
9497 if (return_type_name.empty())
9498 return_type_name =
"void";
9500 repr = return_type_name;
9502 if (!class_name.empty())
9505 repr +=
" (" + class_name +
"::*)";
9510 for (vector<string>::const_iterator i = parm_names.begin();
9511 i != parm_names.end();
9514 if (i != parm_names.begin())
9523 case DW_TAG_string_type:
9524 case DW_TAG_ptr_to_member_type:
9525 case DW_TAG_set_type:
9526 case DW_TAG_file_type:
9527 case DW_TAG_packed_type:
9528 case DW_TAG_thrown_type:
9529 case DW_TAG_interface_type:
9530 case DW_TAG_shared_type:
9550 die_qualified_decl_name(
const reader& rdr,
9551 const Dwarf_Die* die,
9552 size_t where_offset)
9554 if (!die || !die_is_decl(die))
9557 string name = die_name(die);
9559 Dwarf_Die scope_die;
9560 if (!get_scope_die(rdr, die, where_offset, scope_die))
9563 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9564 string separator =
"::";
9568 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9571 case DW_TAG_namespace:
9573 case DW_TAG_variable:
9574 repr = scope_name.empty() ? name : scope_name + separator + name;
9576 case DW_TAG_subprogram:
9577 repr = die_function_signature(rdr, die, where_offset);
9580 case DW_TAG_unspecified_parameters:
9584 case DW_TAG_formal_parameter:
9585 case DW_TAG_imported_declaration:
9586 case DW_TAG_GNU_template_template_param:
9587 case DW_TAG_GNU_template_parameter_pack:
9588 case DW_TAG_GNU_formal_parameter_pack:
9611 die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9613 if (die_is_type(die))
9614 return die_qualified_type_name(rdr, die, where);
9615 else if (die_is_decl(die))
9616 return die_qualified_decl_name(rdr, die, where);
9638 die_qualified_type_name_empty(
const reader& rdr,
9639 const Dwarf_Die* die,
9640 size_t where,
string &qualified_name)
9645 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9648 if (tag == DW_TAG_typedef
9649 || tag == DW_TAG_pointer_type
9650 || tag == DW_TAG_reference_type
9651 || tag == DW_TAG_rvalue_reference_type
9652 || tag == DW_TAG_array_type
9653 || tag == DW_TAG_const_type
9654 || tag == DW_TAG_volatile_type
9655 || tag == DW_TAG_restrict_type)
9657 Dwarf_Die underlying_type_die;
9658 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9661 die_qualified_type_name(rdr, &underlying_type_die, where);
9668 string name = die_qualified_type_name(rdr, die, where);
9673 qname = die_qualified_type_name(rdr, die, where);
9677 qualified_name = qname;
9717 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9718 const Dwarf_Die* die,
9719 size_t where_offset,
9721 string &return_type_name,
9723 vector<string>& parm_names,
9728 Dwarf_Die ret_type_die;
9729 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9730 return_type_name =
"void";
9734 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9735 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9737 if (return_type_name.empty())
9738 return_type_name =
"void";
9740 Dwarf_Die object_pointer_die, class_die;
9742 die_function_type_is_method_type(rdr, die, where_offset,
9744 class_die, is_static);
9749 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9751 Dwarf_Die this_pointer_die;
9752 Dwarf_Die pointed_to_die;
9754 && die_die_attribute(&object_pointer_die, DW_AT_type,
9756 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9757 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9760 string fn_name = die_name(die);
9761 string non_qualified_class_name = die_name(&class_die);
9762 bool is_ctor = fn_name == non_qualified_class_name;
9763 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9765 if (is_ctor || is_dtor)
9766 return_type_name.clear();
9769 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
9772 int child_tag = dwarf_tag(&child);
9773 if (child_tag == DW_TAG_formal_parameter)
9775 Dwarf_Die parm_type_die;
9776 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
9778 string qualified_name =
9780 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
9781 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
9783 if (qualified_name.empty())
9785 parm_names.push_back(qualified_name);
9787 else if (child_tag == DW_TAG_unspecified_parameters)
9790 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
9800 while (dwarf_siblingof(&child, &child) == 0);
9802 if (class_name.empty())
9804 Dwarf_Die parent_die;
9805 if (get_parent_die(rdr, die, parent_die, where_offset))
9807 if (die_is_class_type(&parent_die))
9809 rdr.get_die_qualified_type_name(&parent_die, where_offset);
9826 die_function_signature(
const reader& rdr,
9827 const Dwarf_Die *fn_die,
9828 size_t where_offset)
9832 bool has_lang =
false;
9833 if ((has_lang = get_die_language(fn_die, lang)))
9841 string fn_name = die_linkage_name(fn_die);
9842 if (fn_name.empty())
9843 fn_name = die_name(fn_die);
9853 string return_type_name;
9854 Dwarf_Die ret_type_die;
9855 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
9856 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
9859 if (return_type_name.empty())
9860 return_type_name =
"void";
9862 Dwarf_Die scope_die;
9864 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
9865 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
9866 string fn_name = die_name(fn_die);
9867 if (!scope_name.empty())
9868 fn_name = scope_name +
"::" + fn_name;
9871 vector<string> parm_names;
9872 bool is_const =
false;
9873 bool is_static =
false;
9875 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
9877 return_type_name, class_name,
9878 parm_names, is_const, is_static);
9880 bool is_virtual = die_is_virtual(fn_die);
9882 string repr = class_name.empty() ?
"function" :
"method";
9886 if (!return_type_name.empty())
9887 repr +=
" " + return_type_name;
9889 repr +=
" " + fn_name;
9893 bool some_parm_emitted =
false;
9894 for (vector<string>::const_iterator i = parm_names.begin();
9895 i != parm_names.end();
9898 if (i != parm_names.begin())
9900 if (some_parm_emitted)
9904 if (!is_static && !class_name.empty())
9909 some_parm_emitted =
true;
9940 die_pretty_print_type(reader& rdr,
9941 const Dwarf_Die* die,
9942 size_t where_offset)
9945 || (!die_is_type(die)
9946 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
9951 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9954 case DW_TAG_string_type:
9963 repr =
"string type";
9965 case DW_TAG_unspecified_type:
9966 case DW_TAG_ptr_to_member_type:
9969 case DW_TAG_namespace:
9970 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
9973 case DW_TAG_base_type:
9974 repr = rdr.get_die_qualified_type_name(die, where_offset);
9977 case DW_TAG_typedef:
9979 string qualified_name;
9980 if (!die_qualified_type_name_empty(rdr, die,
9983 repr =
"typedef " + qualified_name;
9987 case DW_TAG_const_type:
9988 case DW_TAG_volatile_type:
9989 case DW_TAG_restrict_type:
9990 case DW_TAG_pointer_type:
9991 case DW_TAG_reference_type:
9992 case DW_TAG_rvalue_reference_type:
9993 repr = rdr.get_die_qualified_type_name(die, where_offset);
9996 case DW_TAG_enumeration_type:
9998 string qualified_name =
9999 rdr.get_die_qualified_type_name(die, where_offset);
10000 repr =
"enum " + qualified_name;
10004 case DW_TAG_structure_type:
10005 case DW_TAG_class_type:
10007 string qualified_name =
10008 rdr.get_die_qualified_type_name(die, where_offset);
10009 repr =
"class " + qualified_name;
10013 case DW_TAG_union_type:
10015 string qualified_name =
10016 rdr.get_die_qualified_type_name(die, where_offset);
10017 repr =
"union " + qualified_name;
10021 case DW_TAG_array_type:
10023 Dwarf_Die element_type_die;
10024 if (!die_die_attribute(die, DW_AT_type, element_type_die))
10026 string element_type_name =
10027 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
10028 if (element_type_name.empty())
10032 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
10035 repr = element_type_name;
10036 repr += array_type_def::subrange_type::vector_as_string(subranges);
10040 case DW_TAG_subrange_type:
10050 repr += die_qualified_type_name(rdr, die, where_offset);
10054 case DW_TAG_subroutine_type:
10055 case DW_TAG_subprogram:
10057 string return_type_name;
10059 vector<string> parm_names;
10060 bool is_const =
false;
10061 bool is_static =
false;
10063 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10065 return_type_name, class_name,
10066 parm_names, is_const,
10068 if (class_name.empty())
10069 repr =
"function type";
10071 repr =
"method type";
10072 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
10076 case DW_TAG_set_type:
10077 case DW_TAG_file_type:
10078 case DW_TAG_packed_type:
10079 case DW_TAG_thrown_type:
10080 case DW_TAG_interface_type:
10081 case DW_TAG_shared_type:
10107 die_pretty_print_decl(reader& rdr,
10108 const Dwarf_Die* die,
10109 size_t where_offset)
10111 if (!die || !die_is_decl(die))
10116 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10119 case DW_TAG_namespace:
10120 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
10123 case DW_TAG_member:
10124 case DW_TAG_variable:
10126 string type_repr =
"void";
10127 Dwarf_Die type_die;
10128 if (die_die_attribute(die, DW_AT_type, type_die))
10129 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
10130 repr = die_qualified_name(rdr, die, where_offset);
10132 repr = type_repr +
" " + repr;
10136 case DW_TAG_subprogram:
10137 repr = die_function_signature(rdr, die, where_offset);
10163 die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10165 if (die_is_type(die))
10166 return die_pretty_print_type(rdr, die, where_offset);
10167 else if (die_is_decl(die))
10168 return die_pretty_print_decl(rdr, die, where_offset);
10191 compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10195 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10196 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10197 if (l_tag != r_tag)
10200 bool result =
false;
10202 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10205 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10207 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10214 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10224 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10241 at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10242 const Dwarf_Die *l,
10243 const Dwarf_Die *r)
10245 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10248 if ((die_is_declaration_only(l) && die_has_no_child(l))
10249 || (die_is_declaration_only(r) && die_has_no_child(r)))
10276 compare_as_type_dies(
const reader& rdr,
10277 const Dwarf_Die *l,
10278 const Dwarf_Die *r)
10284 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
10285 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
10286 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10287 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
10295 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10300 uint64_t l_size = 0, r_size = 0;
10301 die_size_in_bits(l, l_size);
10302 die_size_in_bits(r, r_size);
10304 return l_size == r_size;
10319 compare_as_decl_and_type_dies(
const reader &rdr,
10320 const Dwarf_Die *l,
10321 const Dwarf_Die *r)
10323 if (!compare_as_decl_dies(l, r)
10324 || !compare_as_type_dies(rdr, l, r))
10346 fn_die_equal_by_linkage_name(
const Dwarf_Die *l,
10347 const Dwarf_Die *r)
10355 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10357 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10360 string lname = die_name(l), rname = die_name(r);
10361 string llinkage_name = die_linkage_name(l),
10362 rlinkage_name = die_linkage_name(r);
10364 if (die_is_in_c_or_cplusplus(l)
10365 && die_is_in_c_or_cplusplus(r))
10367 if (!llinkage_name.empty() && !rlinkage_name.empty())
10368 return llinkage_name == rlinkage_name;
10369 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10372 return lname == rname;
10375 return (!llinkage_name.empty()
10376 && !rlinkage_name.empty()
10377 && llinkage_name == rlinkage_name);
10409 try_canonical_die_comparison(
const reader& rdr,
10410 Dwarf_Off l_offset, Dwarf_Off r_offset,
10412 bool& l_has_canonical_die_offset,
10413 bool& r_has_canonical_die_offset,
10414 Dwarf_Off& l_canonical_die_offset,
10415 Dwarf_Off& r_canonical_die_offset,
10418 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10419 if (rdr.debug_die_canonicalization_is_on_
10420 && !rdr.use_canonical_die_comparison_)
10425 l_has_canonical_die_offset =
10426 (l_canonical_die_offset =
10427 rdr.get_canonical_die_offset(l_offset, l_die_source,
10430 r_has_canonical_die_offset =
10431 (r_canonical_die_offset =
10432 rdr.get_canonical_die_offset(r_offset, r_die_source,
10435 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10437 result = (l_canonical_die_offset == r_canonical_die_offset);
10444 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10457 notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10461 #define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10462 notify_die_comparison_failed(l, r)
10464 #define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10477 #define ABG_RETURN(value) \
10480 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10482 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10484 return return_comparison_result(l, r, dies_being_compared, \
10485 value, aggregates_being_compared, \
10486 update_canonical_dies_on_the_fly); \
10497 #define ABG_RETURN_FALSE \
10500 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10501 return return_comparison_result(l, r, dies_being_compared, \
10502 COMPARISON_RESULT_DIFFERENT, \
10503 aggregates_being_compared, \
10504 update_canonical_dies_on_the_fly); \
10519 #define SET_RESULT_TO_FALSE(result, l , r) \
10522 result = COMPARISON_RESULT_DIFFERENT; \
10523 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10539 #define SET_RESULT_TO(result, value, l , r) \
10542 result = (value); \
10543 if (result == COMPARISON_RESULT_DIFFERENT) \
10545 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10549 #define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10552 if (aggregates_being_compared.contains(dies_being_compared)) \
10554 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10555 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10556 ABG_RETURN(result); \
10571 get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10576 bool found_member =
false;
10577 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
10580 found_member = (dwarf_siblingof(member, member) == 0))
10582 int tag = dwarf_tag(member);
10583 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10587 return found_member;
10601 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10606 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10608 || tag == DW_TAG_union_type
10609 || tag == DW_TAG_class_type);
10611 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die),
10617 tag = dwarf_tag(child);
10619 if (!(tag == DW_TAG_member
10620 || tag == DW_TAG_inheritance
10621 || tag == DW_TAG_subprogram))
10622 found_child = get_next_member_sibling_die(child, child);
10624 return found_child;
10647 maybe_propagate_canonical_type(
const reader& rdr,
10648 const Dwarf_Die* l,
10649 const Dwarf_Die* r)
10651 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10652 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10654 if (l_tag != r_tag)
10657 if (is_canon_type_to_be_propagated_tag(l_tag))
10658 propagate_canonical_type(rdr, l, r);
10676 propagate_canonical_type(
const reader& rdr,
10677 const Dwarf_Die* l,
10678 const Dwarf_Die* r)
10687 const die_source l_source = rdr.get_die_source(l);
10688 const die_source r_source = rdr.get_die_source(r);
10690 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
10691 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
10692 bool l_has_canonical_die_offset =
false;
10693 bool r_has_canonical_die_offset =
false;
10694 Dwarf_Off l_canonical_die_offset = 0;
10695 Dwarf_Off r_canonical_die_offset = 0;
10697 l_has_canonical_die_offset =
10698 (l_canonical_die_offset =
10699 rdr.get_canonical_die_offset(l_offset, l_source,
10702 r_has_canonical_die_offset =
10703 (r_canonical_die_offset =
10704 rdr.get_canonical_die_offset(r_offset, r_source,
10708 if (!l_has_canonical_die_offset
10709 && r_has_canonical_die_offset
10712 && l_source == r_source)
10715 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10717 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10718 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10719 rdr.canonical_propagated_count_++;
10757 return_comparison_result(
const Dwarf_Die* l,
10758 const Dwarf_Die* r,
10761 offset_pairs_stack_type& comparison_stack,
10762 bool do_propagate_canonical_type =
true)
10764 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10766 if (result == COMPARISON_RESULT_EQUAL)
10771 if (do_propagate_canonical_type)
10774 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10780 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10793 else if (result == COMPARISON_RESULT_UNKNOWN)
10834 if (comparison_stack.is_redundant(cur_dies)
10835 && comparison_stack.vect_.back() == cur_dies)
10839 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10840 comparison_stack.confirm_canonical_propagated_type(cur_dies);
10842 result = COMPARISON_RESULT_EQUAL;
10844 else if (is_canon_type_to_be_propagated_tag(l_tag)
10845 && comparison_stack.vect_.back() == cur_dies)
10850 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
10851 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10855 else if (result == COMPARISON_RESULT_DIFFERENT)
10872 if (comparison_stack.is_redundant(cur_dies)
10873 && comparison_stack.vect_.back() == cur_dies)
10874 comparison_stack.cancel_canonical_propagated_type(cur_dies);
10882 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10883 result = COMPARISON_RESULT_UNKNOWN;
10884 else if (is_canon_type_to_be_propagated_tag(l_tag)
10885 && !comparison_stack.vect_.empty()
10886 && comparison_stack.vect_.back() == cur_dies)
10891 comparison_stack.erase(cur_dies);
10893 maybe_cache_type_comparison_result(comparison_stack.rdr_,
10894 l_tag, cur_dies, result);
10923 compare_dies(
const reader& rdr,
10924 const Dwarf_Die *l,
const Dwarf_Die *r,
10925 offset_pairs_stack_type& aggregates_being_compared,
10926 bool update_canonical_dies_on_the_fly)
10931 const die_source l_die_source = rdr.get_die_source(l);
10932 const die_source r_die_source = rdr.get_die_source(r);
10934 offset_type l_offset =
10937 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10940 offset_type r_offset =
10943 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
10948 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10949 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10951 if (l_tag != r_tag)
10954 if (l_offset == r_offset)
10955 return COMPARISON_RESULT_EQUAL;
10957 if (rdr.leverage_dwarf_factorization()
10958 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
10959 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
10960 if (l_offset != r_offset)
10961 return COMPARISON_RESULT_DIFFERENT;
10964 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
10965 dies_being_compared,
10969 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
10970 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
10974 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
10976 bool canonical_compare_result =
false;
10977 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
10978 l_die_source, r_die_source,
10979 l_has_canonical_die_offset,
10980 r_has_canonical_die_offset,
10981 l_canonical_die_offset,
10982 r_canonical_die_offset,
10983 canonical_compare_result))
10987 (canonical_compare_result
10988 ? COMPARISON_RESULT_EQUAL
10989 : COMPARISON_RESULT_DIFFERENT),
10999 case DW_TAG_base_type:
11000 case DW_TAG_string_type:
11001 case DW_TAG_unspecified_type:
11002 if (!compare_as_decl_and_type_dies(rdr, l, r))
11006 case DW_TAG_typedef:
11007 case DW_TAG_pointer_type:
11008 case DW_TAG_reference_type:
11009 case DW_TAG_rvalue_reference_type:
11010 case DW_TAG_const_type:
11011 case DW_TAG_volatile_type:
11012 case DW_TAG_restrict_type:
11014 if (!compare_as_type_dies(rdr, l, r))
11020 bool from_the_same_tu =
false;
11021 if (!pointer_or_qual_die_of_anonymous_class_type(l)
11022 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
11023 && from_the_same_tu)
11040 Dwarf_Die lu_type_die, ru_type_die;
11041 bool lu_is_void, ru_is_void;
11043 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
11044 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
11046 if (lu_is_void && ru_is_void)
11047 result = COMPARISON_RESULT_EQUAL;
11048 else if (lu_is_void != ru_is_void)
11051 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
11052 aggregates_being_compared,
11053 update_canonical_dies_on_the_fly);
11057 case DW_TAG_enumeration_type:
11058 if (!compare_as_decl_and_type_dies(rdr, l, r))
11063 Dwarf_Die l_enumtor, r_enumtor;
11064 bool found_l_enumtor =
true, found_r_enumtor =
true;
11066 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11067 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11069 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11071 found_l_enumtor && found_r_enumtor;
11072 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
11073 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
11075 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
11076 if ( l_tag != r_tag)
11082 if (l_tag != DW_TAG_enumerator)
11085 uint64_t l_val = 0, r_val = 0;
11086 die_unsigned_constant_attribute(&l_enumtor,
11089 die_unsigned_constant_attribute(&r_enumtor,
11092 if (l_val != r_val)
11098 if (found_l_enumtor != found_r_enumtor )
11103 case DW_TAG_structure_type:
11104 case DW_TAG_union_type:
11105 case DW_TAG_class_type:
11107 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11109 rdr.compare_count_++;
11111 if (!compare_as_decl_and_type_dies(rdr, l, r))
11113 else if (rdr.options().assume_odr_for_cplusplus
11114 && rdr.odr_is_relevant(l)
11115 && rdr.odr_is_relevant(r)
11116 && !die_is_anonymous(l)
11117 && !die_is_anonymous(r))
11118 result = COMPARISON_RESULT_EQUAL;
11121 aggregates_being_compared.add(dies_being_compared);
11123 Dwarf_Die l_member, r_member;
11124 bool found_l_member =
true, found_r_member =
true;
11126 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11127 for (found_l_member = get_member_child_die(l, &l_member),
11128 found_r_member = get_member_child_die(r, &r_member);
11129 found_l_member && found_r_member;
11130 found_l_member = get_next_member_sibling_die(&l_member,
11132 found_r_member = get_next_member_sibling_die(&r_member,
11135 int l_tag = dwarf_tag(&l_member),
11136 r_tag = dwarf_tag(&r_member);
11138 if (l_tag != r_tag)
11145 || l_tag == DW_TAG_variable
11146 || l_tag == DW_TAG_inheritance
11147 || l_tag == DW_TAG_subprogram);
11150 compare_dies(rdr, &l_member, &r_member,
11151 aggregates_being_compared,
11152 update_canonical_dies_on_the_fly);
11154 if (local_result == COMPARISON_RESULT_UNKNOWN)
11163 result = local_result;
11165 if (local_result == COMPARISON_RESULT_DIFFERENT)
11171 if (found_l_member != found_r_member)
11180 case DW_TAG_array_type:
11182 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11184 aggregates_being_compared.add(dies_being_compared);
11186 rdr.compare_count_++;
11188 Dwarf_Die l_child, r_child;
11189 bool found_l_child, found_r_child;
11190 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11192 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11194 found_l_child && found_r_child;
11195 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11196 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11198 int l_child_tag = dwarf_tag(&l_child),
11199 r_child_tag = dwarf_tag(&r_child);
11200 if (l_child_tag == DW_TAG_subrange_type
11201 || r_child_tag == DW_TAG_subrange_type)
11203 result = compare_dies(rdr, &l_child, &r_child,
11204 aggregates_being_compared,
11205 update_canonical_dies_on_the_fly);
11213 if (found_l_child != found_r_child)
11216 Dwarf_Die ltype_die, rtype_die;
11217 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11218 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11221 result = compare_dies(rdr, <ype_die, &rtype_die,
11222 aggregates_being_compared,
11223 update_canonical_dies_on_the_fly);
11229 case DW_TAG_subrange_type:
11231 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11232 l_upper_bound = 0, r_upper_bound = 0;
11233 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11234 l_upper_bound_set =
false, r_upper_bound_set =
false;
11236 l_lower_bound_set =
11237 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11238 r_lower_bound_set =
11239 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11241 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11244 uint64_t l_count = 0;
11245 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11247 l_upper_bound = l_lower_bound + l_count;
11248 l_upper_bound_set =
true;
11254 l_upper_bound_set =
true;
11256 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11259 uint64_t r_count = 0;
11260 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11262 r_upper_bound = r_lower_bound + r_count;
11263 r_upper_bound_set =
true;
11269 r_upper_bound_set =
true;
11271 if ((l_lower_bound_set != r_lower_bound_set)
11272 || (l_upper_bound_set != r_upper_bound_set)
11273 || (l_lower_bound != r_lower_bound)
11274 || (l_upper_bound != r_upper_bound))
11279 case DW_TAG_subroutine_type:
11280 case DW_TAG_subprogram:
11282 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11284 aggregates_being_compared.add(dies_being_compared);
11286 rdr.compare_count_++;
11288 if (l_tag == DW_TAG_subprogram
11289 && !fn_die_equal_by_linkage_name(l, r))
11294 else if (l_tag == DW_TAG_subprogram
11295 && die_is_in_c(l) && die_is_in_c(r))
11297 result = COMPARISON_RESULT_EQUAL;
11300 else if (!die_is_in_c(l) && !die_is_in_c(r))
11306 Dwarf_Die l_return_type, r_return_type;
11307 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11309 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11311 if (l_return_type_is_void != r_return_type_is_void
11312 || (!l_return_type_is_void
11313 && !compare_dies(rdr,
11314 &l_return_type, &r_return_type,
11315 aggregates_being_compared,
11316 update_canonical_dies_on_the_fly)))
11320 Dwarf_Die l_child, r_child;
11321 bool found_l_child, found_r_child;
11322 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11324 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11326 found_l_child && found_r_child;
11327 found_l_child = dwarf_siblingof(&l_child,
11329 found_r_child = dwarf_siblingof(&r_child,
11332 int l_child_tag = dwarf_tag(&l_child);
11333 int r_child_tag = dwarf_tag(&r_child);
11335 COMPARISON_RESULT_EQUAL;
11336 if (l_child_tag != r_child_tag)
11337 local_result = COMPARISON_RESULT_DIFFERENT;
11338 if (l_child_tag == DW_TAG_formal_parameter)
11340 compare_dies(rdr, &l_child, &r_child,
11341 aggregates_being_compared,
11342 update_canonical_dies_on_the_fly);
11343 if (local_result == COMPARISON_RESULT_DIFFERENT)
11345 result = local_result;
11349 if (local_result == COMPARISON_RESULT_UNKNOWN)
11360 result = local_result;
11362 if (found_l_child != found_r_child)
11372 case DW_TAG_formal_parameter:
11374 Dwarf_Die l_type, r_type;
11375 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11376 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11377 if (l_type_is_void != r_type_is_void)
11379 else if (!l_type_is_void)
11382 compare_dies(rdr, &l_type, &r_type,
11383 aggregates_being_compared,
11384 update_canonical_dies_on_the_fly);
11390 case DW_TAG_variable:
11391 case DW_TAG_member:
11392 if (compare_as_decl_dies(l, r))
11395 if (l_tag == DW_TAG_member)
11397 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11398 die_member_offset(rdr, l, l_offset_in_bits);
11399 die_member_offset(rdr, r, r_offset_in_bits);
11400 if (l_offset_in_bits != r_offset_in_bits)
11406 Dwarf_Die l_type, r_type;
11407 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11408 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11410 compare_dies(rdr, &l_type, &r_type,
11411 aggregates_being_compared,
11412 update_canonical_dies_on_the_fly);
11420 case DW_TAG_inheritance:
11422 Dwarf_Die l_type, r_type;
11423 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11424 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11425 result = compare_dies(rdr, &l_type, &r_type,
11426 aggregates_being_compared,
11427 update_canonical_dies_on_the_fly);
11431 uint64_t l_a = 0, r_a = 0;
11432 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11433 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11437 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11438 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11442 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11443 die_member_offset(rdr, l, l_offset_in_bits);
11444 die_member_offset(rdr, r, r_offset_in_bits);
11445 if (l_offset_in_bits != r_offset_in_bits)
11450 case DW_TAG_ptr_to_member_type:
11452 bool comp_result =
false;
11453 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11457 Dwarf_Die l_type, r_type;
11458 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11459 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11460 result = compare_dies(rdr, &l_type, &r_type,
11461 aggregates_being_compared,
11462 update_canonical_dies_on_the_fly);
11466 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11467 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11468 result = compare_dies(rdr, &l_type, &r_type,
11469 aggregates_being_compared,
11470 update_canonical_dies_on_the_fly);
11476 case DW_TAG_enumerator:
11477 case DW_TAG_packed_type:
11478 case DW_TAG_set_type:
11479 case DW_TAG_file_type:
11480 case DW_TAG_thrown_type:
11481 case DW_TAG_interface_type:
11482 case DW_TAG_shared_type:
11483 case DW_TAG_compile_unit:
11484 case DW_TAG_namespace:
11485 case DW_TAG_module:
11486 case DW_TAG_constant:
11487 case DW_TAG_partial_unit:
11488 case DW_TAG_imported_unit:
11489 case DW_TAG_dwarf_procedure:
11490 case DW_TAG_imported_declaration:
11491 case DW_TAG_entry_point:
11493 case DW_TAG_lexical_block:
11494 case DW_TAG_unspecified_parameters:
11495 case DW_TAG_variant:
11496 case DW_TAG_common_block:
11497 case DW_TAG_common_inclusion:
11498 case DW_TAG_inlined_subroutine:
11499 case DW_TAG_with_stmt:
11500 case DW_TAG_access_declaration:
11501 case DW_TAG_catch_block:
11502 case DW_TAG_friend:
11503 case DW_TAG_namelist:
11504 case DW_TAG_namelist_item:
11505 case DW_TAG_template_type_parameter:
11506 case DW_TAG_template_value_parameter:
11507 case DW_TAG_try_block:
11508 case DW_TAG_variant_part:
11509 case DW_TAG_imported_module:
11510 case DW_TAG_condition:
11511 case DW_TAG_type_unit:
11512 case DW_TAG_template_alias:
11513 case DW_TAG_lo_user:
11514 case DW_TAG_MIPS_loop:
11515 case DW_TAG_format_label:
11516 case DW_TAG_function_template:
11517 case DW_TAG_class_template:
11518 case DW_TAG_GNU_BINCL:
11519 case DW_TAG_GNU_EINCL:
11520 case DW_TAG_GNU_template_template_param:
11521 case DW_TAG_GNU_template_parameter_pack:
11522 case DW_TAG_GNU_formal_parameter_pack:
11523 case DW_TAG_GNU_call_site:
11524 case DW_TAG_GNU_call_site_parameter:
11525 case DW_TAG_hi_user:
11526 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11527 if (rdr.debug_die_canonicalization_is_on_)
11554 compare_dies(
const reader& rdr,
11555 const Dwarf_Die *l,
11556 const Dwarf_Die *r,
11557 bool update_canonical_dies_on_the_fly)
11559 offset_pairs_stack_type aggregates_being_compared(rdr);
11560 return compare_dies(rdr, l, r, aggregates_being_compared,
11561 update_canonical_dies_on_the_fly);
11583 compare_dies_during_canonicalization(reader& rdr,
11584 const Dwarf_Die *l,
11585 const Dwarf_Die *r,
11586 bool update_canonical_dies_on_the_fly)
11588 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11589 if (rdr.debug_die_canonicalization_is_on_)
11591 bool canonical_equality =
false, structural_equality =
false;
11592 rdr.use_canonical_die_comparison_ =
false;
11593 structural_equality = compare_dies(rdr, l, r,
11595 rdr.use_canonical_die_comparison_ =
true;
11596 canonical_equality = compare_dies(rdr, l, r,
11597 update_canonical_dies_on_the_fly);
11598 if (canonical_equality != structural_equality)
11600 std::cerr <<
"structural & canonical equality different for DIEs: "
11602 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11603 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11606 << rdr.get_die_pretty_type_representation(l, 0)
11611 return structural_equality;
11614 return compare_dies(rdr, l, r,
11615 update_canonical_dies_on_the_fly);
11657 find_import_unit_point_between_dies(
const reader& rdr,
11658 size_t partial_unit_offset,
11659 Dwarf_Off first_die_offset,
11660 Dwarf_Off first_die_cu_offset,
11662 size_t last_die_offset,
11663 size_t& imported_point_offset)
11666 rdr.tu_die_imported_unit_points_map(source);
11668 tu_die_imported_unit_points_map_type::const_iterator iter =
11669 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11671 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11674 if (imported_unit_points.empty())
11677 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11678 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11680 find_lower_bound_in_imported_unit_points(imported_unit_points,
11684 if (last_die_offset !=
static_cast<size_t>(-1))
11685 find_lower_bound_in_imported_unit_points(imported_unit_points,
11689 if (e != imported_unit_points.end())
11691 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11692 if (i->imported_unit_die_off == partial_unit_offset)
11694 imported_point_offset = i->offset_of_import ;
11698 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11700 if (find_import_unit_point_between_dies(rdr,
11701 partial_unit_offset,
11702 i->imported_unit_child_off,
11703 i->imported_unit_cu_off,
11704 i->imported_unit_die_source,
11706 imported_point_offset))
11712 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11713 if (i->imported_unit_die_off == partial_unit_offset)
11715 imported_point_offset = i->offset_of_import ;
11719 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11721 if (find_import_unit_point_between_dies(rdr,
11722 partial_unit_offset,
11723 i->imported_unit_child_off,
11724 i->imported_unit_cu_off,
11725 i->imported_unit_die_source,
11727 imported_point_offset))
11760 find_import_unit_point_before_die(
const reader& rdr,
11761 size_t partial_unit_offset,
11762 size_t where_offset,
11763 size_t& imported_point_offset)
11765 size_t import_point_offset = 0;
11766 Dwarf_Die first_die_of_tu;
11768 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
11769 &first_die_of_tu) != 0)
11772 Dwarf_Die cu_die_memory;
11775 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
11776 &cu_die_memory, 0, 0);
11778 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
11779 dwarf_dieoffset(&first_die_of_tu),
11780 dwarf_dieoffset(cu_die),
11781 PRIMARY_DEBUG_INFO_DIE_SOURCE,
11783 import_point_offset))
11785 imported_point_offset = import_point_offset;
11789 if (import_point_offset)
11791 imported_point_offset = import_point_offset;
11819 get_parent_die(
const reader& rdr,
11820 const Dwarf_Die* die,
11821 Dwarf_Die& parent_die,
11822 size_t where_offset)
11826 const die_source source = rdr.get_die_source(die);
11829 offset_offset_map_type::const_iterator i =
11830 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
11837 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
11838 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11839 i->second, &parent_die));
11841 case ALT_DEBUG_INFO_DIE_SOURCE:
11842 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
11843 i->second, &parent_die));
11845 case TYPE_UNIT_DIE_SOURCE:
11846 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11847 i->second, &parent_die));
11849 case NO_DEBUG_INFO_DIE_SOURCE:
11850 case NUMBER_OF_DIE_SOURCES:
11854 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
11856 if (where_offset == 0)
11858 parent_die = *rdr.cur_tu_die();
11861 size_t import_point_offset = 0;
11863 find_import_unit_point_before_die(rdr,
11864 dwarf_dieoffset(&parent_die),
11866 import_point_offset);
11872 parent_die = *rdr.cur_tu_die();
11876 Dwarf_Die import_point_die;
11877 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11878 import_point_offset,
11879 &import_point_die));
11880 return get_parent_die(rdr, &import_point_die,
11881 parent_die, where_offset);
11914 get_scope_die(
const reader& rdr,
11915 const Dwarf_Die* dye,
11916 size_t where_offset,
11917 Dwarf_Die& scope_die)
11919 Dwarf_Die origin_die_mem;
11920 Dwarf_Die *die = &origin_die_mem;
11921 if (!die_origin_die(dye, origin_die_mem))
11922 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
11925 get_die_language(die, die_lang);
11927 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
11929 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
11930 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
11933 if (!get_parent_die(rdr, die, scope_die, where_offset))
11936 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
11937 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
11938 || dwarf_tag(&scope_die) == DW_TAG_array_type)
11939 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
11969 get_scope_for_die(reader& rdr,
11971 bool called_for_public_decl,
11972 size_t where_offset)
11974 Dwarf_Die origin_die_mem;
11975 Dwarf_Die *die = &origin_die_mem;
11977 if (!die_origin_die(dye, origin_die_mem))
11980 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
11982 const die_source source_of_die = rdr.get_die_source(die);
11985 get_die_language(die, die_lang);
11987 || rdr.die_parent_map(source_of_die).empty())
11992 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
11993 return rdr.global_scope();
11996 Dwarf_Die parent_die;
11998 if (!get_parent_die(rdr, die, parent_die, where_offset))
11999 return rdr.nil_scope();
12001 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
12002 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
12003 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
12005 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
12006 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
12008 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
12009 || source_of_die == TYPE_UNIT_DIE_SOURCE);
12010 return rdr.cur_transl_unit()->get_global_scope();
12019 die_tu_map_type::const_iterator i =
12020 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
12021 if (i != rdr.die_tu_map().end())
12022 return i->second->get_global_scope();
12023 return rdr.cur_transl_unit()->get_global_scope();
12028 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
12029 || dwarf_tag(&parent_die) == DW_TAG_array_type
12030 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
12042 called_for_public_decl,
12051 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
12052 return rdr.nil_scope();
12053 s = get_scope_for_die(rdr, &parent_die,
12054 called_for_public_decl,
12060 d = build_ir_node_from_die(rdr, &parent_die,
12061 called_for_public_decl,
12063 s = dynamic_pointer_cast<scope_decl>(d);
12067 return rdr.nil_scope();
12070 if (cl && cl->get_is_declaration_only())
12073 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
12090 dwarf_language_to_tu_language(
size_t l)
12095 return translation_unit::LANG_C89;
12097 return translation_unit::LANG_C;
12098 case DW_LANG_Ada83:
12099 return translation_unit::LANG_Ada83;
12100 case DW_LANG_C_plus_plus:
12101 return translation_unit::LANG_C_plus_plus;
12102 case DW_LANG_Cobol74:
12103 return translation_unit::LANG_Cobol74;
12104 case DW_LANG_Cobol85:
12105 return translation_unit::LANG_Cobol85;
12106 case DW_LANG_Fortran77:
12107 return translation_unit::LANG_Fortran77;
12108 case DW_LANG_Fortran90:
12109 return translation_unit::LANG_Fortran90;
12110 case DW_LANG_Pascal83:
12111 return translation_unit::LANG_Pascal83;
12112 case DW_LANG_Modula2:
12113 return translation_unit::LANG_Modula2;
12115 return translation_unit::LANG_Java;
12117 return translation_unit::LANG_C99;
12118 case DW_LANG_Ada95:
12119 return translation_unit::LANG_Ada95;
12120 case DW_LANG_Fortran95:
12121 return translation_unit::LANG_Fortran95;
12123 return translation_unit::LANG_PLI;
12125 return translation_unit::LANG_ObjC;
12126 case DW_LANG_ObjC_plus_plus:
12127 return translation_unit::LANG_ObjC_plus_plus;
12129 #ifdef HAVE_DW_LANG_Rust_enumerator
12131 return translation_unit::LANG_Rust;
12134 #ifdef HAVE_DW_LANG_UPC_enumerator
12136 return translation_unit::LANG_UPC;
12139 #ifdef HAVE_DW_LANG_D_enumerator
12141 return translation_unit::LANG_D;
12144 #ifdef HAVE_DW_LANG_Python_enumerator
12145 case DW_LANG_Python:
12146 return translation_unit::LANG_Python;
12149 #ifdef HAVE_DW_LANG_Go_enumerator
12151 return translation_unit::LANG_Go;
12154 #ifdef HAVE_DW_LANG_C11_enumerator
12156 return translation_unit::LANG_C11;
12159 #ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12160 case DW_LANG_C_plus_plus_03:
12161 return translation_unit::LANG_C_plus_plus_03;
12164 #ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12165 case DW_LANG_C_plus_plus_11:
12166 return translation_unit::LANG_C_plus_plus_11;
12169 #ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12170 case DW_LANG_C_plus_plus_14:
12171 return translation_unit::LANG_C_plus_plus_14;
12174 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12175 case DW_LANG_Mips_Assembler:
12176 return translation_unit::LANG_Mips_Assembler;
12180 return translation_unit::LANG_UNKNOWN;
12197 case translation_unit::LANG_UNKNOWN:
12200 case translation_unit::LANG_Cobol74:
12201 case translation_unit::LANG_Cobol85:
12204 case translation_unit::LANG_C89:
12205 case translation_unit::LANG_C99:
12206 case translation_unit::LANG_C11:
12207 case translation_unit::LANG_C:
12208 case translation_unit::LANG_C_plus_plus_03:
12209 case translation_unit::LANG_C_plus_plus_11:
12210 case translation_unit::LANG_C_plus_plus_14:
12211 case translation_unit::LANG_C_plus_plus:
12212 case translation_unit::LANG_ObjC:
12213 case translation_unit::LANG_ObjC_plus_plus:
12214 case translation_unit::LANG_Rust:
12217 case translation_unit::LANG_Fortran77:
12218 case translation_unit::LANG_Fortran90:
12219 case translation_unit::LANG_Fortran95:
12220 case translation_unit::LANG_Ada83:
12221 case translation_unit::LANG_Ada95:
12222 case translation_unit::LANG_Pascal83:
12223 case translation_unit::LANG_Modula2:
12226 case translation_unit::LANG_Java:
12229 case translation_unit::LANG_PLI:
12232 case translation_unit::LANG_UPC:
12233 case translation_unit::LANG_D:
12234 case translation_unit::LANG_Python:
12235 case translation_unit::LANG_Go:
12236 case translation_unit::LANG_Mips_Assembler:
12263 imported_unit_points_type::const_iterator& r)
12265 imported_unit_point v(val);
12266 imported_unit_points_type::const_iterator result =
12267 std::lower_bound(p.begin(), p.end(), v);
12269 bool is_ok = result != p.end();
12291 build_translation_unit_and_add_to_ir(reader& rdr,
12299 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12303 rdr.clear_per_translation_unit_data();
12305 rdr.cur_tu_die(die);
12307 string path = die_string_attribute(die, DW_AT_name);
12308 if (path ==
"<artificial>")
12314 std::ostringstream o;
12315 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12318 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12328 const string& abs_path =
12329 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12330 result = rdr.corpus()->find_translation_unit(abs_path);
12335 result.reset(
new translation_unit(rdr.env(),
12338 result->set_compilation_dir_path(compilation_dir);
12339 rdr.corpus()->add(result);
12341 die_unsigned_constant_attribute(die, DW_AT_language, l);
12342 result->set_language(dwarf_language_to_tu_language(l));
12345 rdr.cur_transl_unit(result);
12346 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12349 if (dwarf_child(die, &child) != 0)
12352 result->set_is_constructed(
false);
12353 int tag = dwarf_tag(&child);
12355 if (rdr.load_undefined_interfaces()
12356 && (rdr.is_decl_die_with_undefined_symbol(&child)
12357 || tag == DW_TAG_class_type
12362 || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
12363 && die_is_in_cplus_plus(&child))))
12367 build_ir_node_from_die(rdr, &child,
12372 dwarf_dieoffset(&child));
12374 else if (!rdr.env().analyze_exported_interfaces_only()
12375 || rdr.is_decl_die_with_exported_symbol(&child))
12379 build_ir_node_from_die(rdr, &child,
12380 die_is_public_decl(&child),
12381 dwarf_dieoffset(&child));
12383 while (dwarf_siblingof(&child, &child) == 0);
12385 if (!rdr.var_decls_to_re_add_to_tree().empty())
12386 for (list<var_decl_sptr>::const_iterator v =
12387 rdr.var_decls_to_re_add_to_tree().begin();
12388 v != rdr.var_decls_to_re_add_to_tree().end();
12395 string demangled_name =
12397 if (!demangled_name.empty())
12399 std::list<string> fqn_comps;
12401 string mem_name = fqn_comps.back();
12402 fqn_comps.pop_back();
12405 if (!fqn_comps.empty())
12433 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12439 rdr.var_decls_to_re_add_to_tree().clear();
12441 result->set_is_constructed(
true);
12466 build_namespace_decl_and_add_to_ir(reader& rdr,
12468 size_t where_offset)
12475 unsigned tag = dwarf_tag(die);
12476 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12483 string name, linkage_name;
12485 die_loc_and_name(rdr, die, loc, name, linkage_name);
12487 result.reset(
new namespace_decl(rdr.env(), name, loc));
12489 rdr.associate_die_to_decl(die, result, where_offset);
12492 if (dwarf_child(die, &child) != 0)
12495 rdr.scope_stack().push(result.get());
12497 build_ir_node_from_die(rdr, &child,
12503 die_is_public_decl(die) && die_is_public_decl(&child),
12505 while (dwarf_siblingof(&child, &child) == 0);
12506 rdr.scope_stack().pop();
12521 build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12527 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12529 uint64_t byte_size = 0, bit_size = 0;
12530 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12531 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12534 if (bit_size == 0 && byte_size != 0)
12536 bit_size = byte_size * 8;
12538 string type_name, linkage_name;
12540 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12542 if (byte_size == 0)
12546 if (type_name ==
"void")
12547 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12554 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12556 string normalized_type_name = type_name;
12557 integral_type int_type;
12559 normalized_type_name = int_type.
to_string();
12564 if (corpus_sptr corp = rdr.corpus())
12567 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12568 0, loc, linkage_name));
12569 rdr.associate_die_to_type(die, result, where_offset);
12587 build_enum_underlying_type(reader& rdr,
12589 uint64_t enum_size,
12590 bool is_anonymous =
true)
12592 string underlying_type_name =
12596 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12597 enum_size, enum_size, location()));
12598 result->set_is_anonymous(is_anonymous);
12599 result->set_is_artificial(
true);
12602 result = dynamic_pointer_cast<type_decl>(d);
12623 build_enum_type(reader& rdr,
12626 size_t where_offset,
12627 bool is_declaration_only)
12633 unsigned tag = dwarf_tag(die);
12634 if (tag != DW_TAG_enumeration_type)
12637 string name, linkage_name;
12639 die_loc_and_name(rdr, die, loc, name, linkage_name);
12641 bool is_anonymous =
false;
12645 name = get_internal_anonymous_die_prefix_name(die);
12648 is_anonymous =
true;
12650 if (
size_t s = scope->get_num_anonymous_member_enums())
12651 name = build_internal_anonymous_die_name(name, s);
12654 bool use_odr = rdr.odr_is_relevant(die);
12666 result = pre_existing_enum;
12668 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12677 if (pre_existing_enum->get_location() == loc)
12678 result = pre_existing_enum;
12683 rdr.associate_die_to_type(die, result, where_offset);
12691 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12693 bool is_artificial = die_is_artificial(die);
12696 bool enum_underlying_type_is_anonymous=
true;
12700 if (dwarf_child(die, &child) == 0)
12704 if (dwarf_tag(&child) != DW_TAG_enumerator)
12709 die_loc_and_name(rdr, &child, l, n, m);
12711 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12712 enms.push_back(enum_type_decl::enumerator(n, val));
12714 while (dwarf_siblingof(&child, &child) == 0);
12722 build_enum_underlying_type(rdr, name, size,
12723 enum_underlying_type_is_anonymous);
12724 t->set_is_declaration_only(is_declaration_only);
12726 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12727 result->set_is_anonymous(is_anonymous);
12728 result->set_is_declaration_only(is_declaration_only);
12729 result->set_is_artificial(is_artificial);
12730 rdr.associate_die_to_type(die, result, where_offset);
12732 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12751 finish_member_function_reading(Dwarf_Die* die,
12753 const class_or_union_sptr klass,
12764 size_t is_inline = die_is_declared_inline(die);
12765 bool is_ctor = (f->get_name() == klass->get_name());
12766 bool is_dtor = (!f->get_name().empty()
12767 &&
static_cast<string>(f->get_name())[0] ==
'~');
12768 bool is_virtual = die_is_virtual(die);
12769 int64_t vindex = -1;
12771 die_virtual_function_index(die, vindex);
12774 if (!c->is_struct())
12775 access = private_access;
12776 die_access_specifier(die, access);
12778 bool is_static =
false;
12786 if (!f->get_parameters().empty())
12787 first_parm = f->get_parameters()[0];
12789 bool is_artificial = first_parm && first_parm->get_is_artificial();
12790 type_base_sptr this_ptr_type, other_klass;
12793 this_ptr_type = first_parm->get_type();
12800 this_ptr_type = q->get_underlying_type();
12804 other_klass = p->get_pointed_to_type();
12809 other_klass = q->get_underlying_type();
12812 &&
get_type_name(other_klass) == klass->get_qualified_name())
12823 Dwarf_Die object_pointer_die;
12824 if (die_has_object_pointer(die, object_pointer_die))
12828 m->is_declared_inline(is_inline);
12841 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
12860 Dwarf_Off die_offset = dwarf_dieoffset(die);
12862 rdr.die_function_decl_with_no_symbol_map();
12863 die_function_decl_map_type::const_iterator i =
12864 fns_with_no_symbol.find(die_offset);
12865 if (i == fns_with_no_symbol.end())
12866 fns_with_no_symbol[die_offset] = f;
12887 maybe_finish_function_decl_reading(reader& rdr,
12889 size_t where_offset,
12907 static type_base_sptr
12908 lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
12911 corpus* corp = scope->get_corpus();
12932 static type_base_sptr
12933 lookup_class_or_typedef_from_corpus(reader& rdr,
12935 bool called_for_public_decl,
12936 size_t where_offset)
12941 string class_name = die_string_attribute(die, DW_AT_name);
12942 if (class_name.empty())
12946 called_for_public_decl,
12949 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
12951 return type_base_sptr();
12962 static type_base_sptr
12963 lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
12964 const string& type_name)
12967 corpus* corp = scope->get_corpus();
12985 static type_base_sptr
12986 lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
12987 size_t anonymous_member_type_idx,
12993 string type_name = die_string_attribute(die, DW_AT_name);
12996 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
12998 if (type_name.empty())
13001 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
13019 static method_decl_sptr
13020 is_function_for_die_a_member_of_class(reader& rdr,
13021 Dwarf_Die* function_die,
13022 const class_or_union_sptr& class_type)
13027 return method_decl_sptr();
13033 method_type = method->get_type();
13038 class_or_union_sptr method_class = method_type->get_class_type();
13041 string method_class_name = method_class->get_qualified_name(),
13042 class_type_name = class_type->get_qualified_name();
13044 if (method_class_name == class_type_name)
13050 return method_decl_sptr();
13072 static method_decl_sptr
13073 add_or_update_member_function(reader& rdr,
13074 Dwarf_Die* function_die,
13075 const class_or_union_sptr& class_type,
13076 bool called_from_public_decl,
13077 size_t where_offset)
13079 method_decl_sptr method =
13080 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
13083 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
13085 called_from_public_decl,
13088 return method_decl_sptr();
13090 finish_member_function_reading(function_die,
13133 add_or_update_class_type(reader& rdr,
13138 bool called_from_public_decl,
13139 size_t where_offset,
13140 bool is_declaration_only)
13146 const die_source source = rdr.get_die_source(die);
13148 unsigned tag = dwarf_tag(die);
13150 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
13154 die_class_or_union_map_type::const_iterator i =
13155 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13156 if (i != rdr.die_wip_classes_map(source).end())
13164 string name, linkage_name;
13166 die_loc_and_name(rdr, die, loc, name, linkage_name);
13168 bool is_anonymous =
false;
13173 name = get_internal_anonymous_die_prefix_name(die);
13176 is_anonymous =
true;
13178 if (
size_t s = scope->get_num_anonymous_member_classes())
13179 name = build_internal_anonymous_die_name(name, s);
13184 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13200 && (result->get_is_declaration_only() == is_declaration_only
13201 || (!result->get_is_declaration_only()
13202 && is_declaration_only)))
13204 rdr.associate_die_to_type(die, result, where_offset);
13223 klass = pre_existing_class;
13226 die_size_in_bits(die, size);
13227 bool is_artificial = die_is_artificial(die);
13230 bool has_child = (dwarf_child(die, &child) == 0);
13232 decl_base_sptr res;
13235 res = result = klass;
13236 if (has_child && klass->get_is_declaration_only()
13237 && klass->get_definition_of_declaration())
13238 res = result =
is_class_type(klass->get_definition_of_declaration());
13240 result->set_location(loc);
13244 result.reset(
new class_decl(rdr.env(), name, size,
13246 decl_base::VISIBILITY_DEFAULT,
13249 result->set_is_declaration_only(is_declaration_only);
13252 result = dynamic_pointer_cast<class_decl>(res);
13256 if (!klass || klass->get_is_declaration_only())
13257 if (size != result->get_size_in_bits())
13258 result->set_size_in_bits(size);
13263 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13276 result->set_is_declaration_only(is_declaration_only);
13280 if (!result->get_is_declaration_only() && has_child)
13281 if (result->get_size_in_bits() == 0 && size != 0)
13282 result->set_size_in_bits(size);
13284 result->set_is_artificial(is_artificial);
13286 rdr.associate_die_to_type(die, result, where_offset);
13288 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13295 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13297 bool is_incomplete_type =
false;
13298 if (is_declaration_only && size == 0 && has_child)
13310 is_incomplete_type =
true;
13313 dynamic_pointer_cast<scope_decl>(res);
13315 rdr.scope_stack().push(scop.get());
13317 if (has_child && !is_incomplete_type)
13319 int anonymous_member_class_index = -1;
13320 int anonymous_member_union_index = -1;
13321 int anonymous_member_enum_index = -1;
13325 tag = dwarf_tag(&child);
13328 if (tag == DW_TAG_inheritance)
13330 result->set_is_declaration_only(
false);
13332 Dwarf_Die type_die;
13333 if (!die_die_attribute(&child, DW_AT_type, type_die))
13336 type_base_sptr base_type;
13338 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13339 called_from_public_decl,
13343 is_type(build_ir_node_from_die(rdr, &type_die,
13344 called_from_public_decl,
13358 die_access_specifier(&child, access);
13360 bool is_virt= die_is_virtual(&child);
13361 int64_t offset = 0;
13362 bool is_offset_present =
13363 die_member_offset(rdr, &child, offset);
13367 is_offset_present ? offset : -1,
13369 if (b->get_is_declaration_only()
13376 && !b->get_qualified_name().empty())
13377 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13378 if (result->find_base_class(b->get_qualified_name()))
13380 result->add_base_specifier(base);
13383 else if (tag == DW_TAG_member
13384 || tag == DW_TAG_variable)
13386 Dwarf_Die type_die;
13387 if (!die_die_attribute(&child, DW_AT_type, type_die))
13392 die_loc_and_name(rdr, &child, loc, n, m);
13397 if (n.substr(0, 5) ==
"_vptr"
13399 && !std::isalnum(n.at(5))
13409 int64_t offset_in_bits = 0;
13410 bool is_laid_out = die_member_offset(rdr, &child,
13415 bool is_static = !is_laid_out;
13417 if (is_static && variable_is_suppressed(rdr,
13420 is_declaration_only))
13423 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13424 called_from_public_decl,
13426 type_base_sptr t =
is_type(ty);
13430 if (n.empty() && !die_is_anonymous_data_member(&child))
13436 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13453 result->set_is_declaration_only(
false);
13459 die_access_specifier(&child, access);
13467 result->add_data_member(dm, access, is_laid_out,
13468 is_static, offset_in_bits);
13470 rdr.associate_die_to_decl(&child, dm, where_offset,
13474 else if (tag == DW_TAG_subprogram)
13477 add_or_update_member_function(rdr, &child, result,
13478 called_from_public_decl,
13481 rdr.associate_die_to_decl(&child, f, where_offset,
13485 else if (die_is_type(&child))
13491 int anonymous_member_type_index = 0;
13495 if (die_is_class_type(&child))
13496 anonymous_member_type_index =
13497 ++anonymous_member_class_index;
13498 else if (dwarf_tag(&child) == DW_TAG_union_type)
13499 anonymous_member_type_index =
13500 ++anonymous_member_union_index;
13501 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13502 anonymous_member_type_index =
13503 ++anonymous_member_enum_index;
13508 && !lookup_class_typedef_or_enum_type_from_corpus
13509 (&child, anonymous_member_type_index, result.get()))
13510 || !result->find_member_type(die_name(&child)))
13511 build_ir_node_from_die(rdr, &child, result.get(),
13512 called_from_public_decl,
13515 }
while (dwarf_siblingof(&child, &child) == 0);
13518 rdr.scope_stack().pop();
13521 die_class_or_union_map_type::const_iterator i =
13522 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13523 if (i != rdr.die_wip_classes_map(source).end())
13528 rdr.die_wip_classes_map(source).erase(i);
13532 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13560 static union_decl_sptr
13561 add_or_update_union_type(reader& rdr,
13564 union_decl_sptr union_type,
13565 bool called_from_public_decl,
13566 size_t where_offset,
13567 bool is_declaration_only)
13569 union_decl_sptr result;
13573 unsigned tag = dwarf_tag(die);
13575 if (tag != DW_TAG_union_type)
13578 const die_source source = rdr.get_die_source(die);
13580 die_class_or_union_map_type::const_iterator i =
13581 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13582 if (i != rdr.die_wip_classes_map(source).end())
13590 string name, linkage_name;
13592 die_loc_and_name(rdr, die, loc, name, linkage_name);
13594 bool is_anonymous =
false;
13599 name = get_internal_anonymous_die_prefix_name(die);
13602 is_anonymous =
true;
13604 if (
size_t s = scope->get_num_anonymous_member_unions())
13605 name = build_internal_anonymous_die_name(name, s);
13615 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13624 rdr.associate_die_to_type(die, result, where_offset);
13636 if (union_decl_sptr pre_existing_union =
13638 union_type = pre_existing_union;
13641 die_size_in_bits(die, size);
13642 bool is_artificial = die_is_artificial(die);
13646 result = union_type;
13647 result->set_location(loc);
13651 result.reset(
new union_decl(rdr.env(), name, size, loc,
13652 decl_base::VISIBILITY_DEFAULT,
13654 if (is_declaration_only)
13655 result->set_is_declaration_only(
true);
13662 result->set_size_in_bits(size);
13663 result->set_is_declaration_only(
false);
13666 result->set_is_artificial(is_artificial);
13668 rdr.associate_die_to_type(die, result, where_offset);
13670 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13673 bool has_child = (dwarf_child(die, &child) == 0);
13677 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13680 dynamic_pointer_cast<scope_decl>(result);
13682 rdr.scope_stack().push(scop.get());
13688 tag = dwarf_tag(&child);
13690 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13692 Dwarf_Die type_die;
13693 if (!die_die_attribute(&child, DW_AT_type, type_die))
13698 die_loc_and_name(rdr, &child, loc, n, m);
13707 ssize_t offset_in_bits = 0;
13708 decl_base_sptr ty =
13709 is_decl(build_ir_node_from_die(rdr, &type_die,
13710 called_from_public_decl,
13712 type_base_sptr t =
is_type(ty);
13719 result->set_is_declaration_only(
false);
13722 die_access_specifier(&child, access);
13728 if (n.empty() && result->find_data_member(dm))
13734 result->add_data_member(dm, access,
true,
13738 rdr.associate_die_to_decl(&child, dm, where_offset,
13742 else if (tag == DW_TAG_subprogram)
13745 is_decl(build_ir_node_from_die(rdr, &child,
13747 called_from_public_decl,
13755 finish_member_function_reading(&child, f, result, rdr);
13757 rdr.associate_die_to_decl(&child, f, where_offset,
13761 else if (die_is_type(&child))
13762 decl_base_sptr td =
13763 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13764 called_from_public_decl,
13766 }
while (dwarf_siblingof(&child, &child) == 0);
13769 rdr.scope_stack().pop();
13772 die_class_or_union_map_type::const_iterator i =
13773 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13774 if (i != rdr.die_wip_classes_map(source).end())
13779 rdr.die_wip_classes_map(source).erase(i);
13803 static type_base_sptr
13804 build_qualified_type(reader& rdr,
13806 bool called_from_public_decl,
13807 size_t where_offset)
13809 type_base_sptr result;
13813 unsigned tag = dwarf_tag(die);
13815 if (tag != DW_TAG_const_type
13816 && tag != DW_TAG_volatile_type
13817 && tag != DW_TAG_restrict_type)
13820 Dwarf_Die underlying_type_die;
13821 decl_base_sptr utype_decl;
13822 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13826 utype_decl = build_ir_node_for_void_type(rdr);
13829 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
13830 called_from_public_decl,
13837 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13840 rdr.associate_die_to_type(die, result, where_offset);
13844 type_base_sptr utype =
is_type(utype_decl);
13848 if (tag == DW_TAG_const_type)
13849 qual |= qualified_type_def::CV_CONST;
13850 else if (tag == DW_TAG_volatile_type)
13851 qual |= qualified_type_def::CV_VOLATILE;
13852 else if (tag == DW_TAG_restrict_type)
13853 qual |= qualified_type_def::CV_RESTRICT;
13858 result.reset(
new qualified_type_def(utype, qual, location()));
13860 rdr.associate_die_to_type(die, result, where_offset);
13878 schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
13883 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13885 rdr.schedule_type_for_late_canonicalization(t);
13889 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13891 rdr.schedule_type_for_late_canonicalization(t);
13895 for (vector<array_type_def::subrange_sptr>::const_iterator i =
13896 type->get_subranges().begin();
13897 i != type->get_subranges().end();
13900 if (!(*i)->get_scope())
13902 rdr.schedule_type_for_late_canonicalization(*i);
13905 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
13907 rdr.schedule_type_for_late_canonicalization(type);
13926 static decl_base_sptr
13927 maybe_strip_qualification(
const qualified_type_def_sptr t,
13933 decl_base_sptr result = t;
13934 type_base_sptr u = t->get_underlying_type();
13938 if (result.get() != t.get())
13944 scope_decl * scope = 0;
13947 scope = array->get_scope();
13950 schedule_array_tree_for_late_canonicalization(array, rdr);
13952 t->set_underlying_type(array);
13953 u = t->get_underlying_type();
13961 schedule_array_tree_for_late_canonicalization(typdef, rdr);
13964 t->set_underlying_type(typdef);
13965 u = t->get_underlying_type();
13974 type_base_sptr element_type = array->get_element_type();
13979 ABG_ASSERT(!qualified->get_canonical_type());
13981 quals |= t->get_cv_quals();
13982 qualified->set_cv_quals(quals);
13988 qualified_type_def_sptr qual_type
13989 (
new qualified_type_def(element_type,
13991 t->get_location()));
13994 array->set_element_type(qual_type);
13995 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
14020 build_pointer_type_def(reader& rdr,
14022 bool called_from_public_decl,
14023 size_t where_offset)
14030 unsigned tag = dwarf_tag(die);
14031 if (tag != DW_TAG_pointer_type)
14035 Dwarf_Die underlying_type_die;
14036 bool has_underlying_type_die =
false;
14037 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14040 utype_decl = build_ir_node_for_void_type(rdr);
14042 has_underlying_type_die =
true;
14044 if (!utype_decl && has_underlying_type_die)
14045 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
14046 called_from_public_decl,
14053 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14060 type_base_sptr utype =
is_type(utype_decl);
14066 uint64_t size = rdr.cur_transl_unit()->get_address_size();
14067 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14074 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
14076 result.reset(
new pointer_type_def(utype, size, 0, location()));
14082 rdr.associate_die_to_type(die, result, where_offset);
14104 build_reference_type(reader& rdr,
14106 bool called_from_public_decl,
14107 size_t where_offset)
14114 unsigned tag = dwarf_tag(die);
14115 if (tag != DW_TAG_reference_type
14116 && tag != DW_TAG_rvalue_reference_type)
14119 Dwarf_Die underlying_type_die;
14120 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14124 build_ir_node_from_die(rdr, &underlying_type_die,
14125 called_from_public_decl,
14132 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14139 type_base_sptr utype =
is_type(utype_decl);
14145 uint64_t size = rdr.cur_transl_unit()->get_address_size();
14146 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14151 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
14153 bool is_lvalue = tag == DW_TAG_reference_type;
14155 result.reset(
new reference_type_def(utype, is_lvalue, size,
14158 if (corpus_sptr corp = rdr.corpus())
14161 rdr.associate_die_to_type(die, result, where_offset);
14184 build_ptr_to_mbr_type(reader& rdr,
14186 bool called_from_public_decl,
14187 size_t where_offset)
14194 unsigned tag = dwarf_tag(die);
14195 if (tag != DW_TAG_ptr_to_member_type)
14198 Dwarf_Die data_member_type_die, containing_type_die;
14200 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
14201 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
14205 build_ir_node_from_die(rdr, &data_member_type_die,
14206 called_from_public_decl, where_offset);
14207 if (!data_member_type)
14211 build_ir_node_from_die(rdr, &containing_type_die,
14212 called_from_public_decl, where_offset);
14213 if (!containing_type)
14220 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14227 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
14229 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
14236 rdr.associate_die_to_type(die, result, where_offset);
14257 build_function_type(reader& rdr,
14259 class_or_union_sptr is_method,
14260 size_t where_offset)
14267 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14268 || dwarf_tag(die) == DW_TAG_subprogram);
14270 const die_source source = rdr.get_die_source(die);
14273 size_t off = dwarf_dieoffset(die);
14274 auto i = rdr.die_wip_function_types_map(source).find(off);
14275 if (i != rdr.die_wip_function_types_map(source).end())
14283 decl_base_sptr type_decl;
14291 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14295 rdr.associate_die_to_type(die, result, where_offset);
14312 rdr.associate_die_to_type(die, fn_type, where_offset);
14320 bool is_const =
false;
14321 bool is_static =
false;
14322 Dwarf_Die object_pointer_die;
14323 Dwarf_Die class_type_die;
14324 bool has_this_parm_die =
14325 die_function_type_is_method_type(rdr, die, where_offset,
14326 object_pointer_die,
14329 if (has_this_parm_die)
14334 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14342 class_or_union_sptr klass_type =
14347 is_method = klass_type;
14356 result.reset(is_method
14357 ?
new method_type(is_method, is_const,
14358 tu->get_address_size(),
14360 :
new function_type(rdr.env(), tu->get_address_size(),
14362 rdr.associate_die_to_type(die, result, where_offset);
14363 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14365 type_base_sptr return_type;
14366 Dwarf_Die ret_type_die;
14367 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14369 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14373 return_type =
is_type(build_ir_node_for_void_type(rdr));
14374 result->set_return_type(return_type);
14379 if (dwarf_child(die, &child) == 0)
14382 int child_tag = dwarf_tag(&child);
14383 if (child_tag == DW_TAG_formal_parameter)
14386 string name, linkage_name;
14388 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14393 bool is_artificial = die_is_artificial(&child);
14394 type_base_sptr parm_type;
14395 Dwarf_Die parm_type_die;
14396 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14398 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14405 && function_parms.empty())
14421 (
new function_decl::parameter(parm_type, name, loc,
14424 function_parms.push_back(p);
14426 else if (child_tag == DW_TAG_unspecified_parameters)
14429 bool is_artificial = die_is_artificial(&child);
14431 type_base_sptr parm_type =
14432 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14434 (
new function_decl::parameter(parm_type,
14439 function_parms.push_back(p);
14449 while (dwarf_siblingof(&child, &child) == 0);
14451 result->set_parameters(function_parms);
14453 tu->bind_function_type_life_time(result);
14455 result->set_is_artificial(
true);
14457 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14460 die_function_type_map_type::const_iterator i =
14461 rdr.die_wip_function_types_map(source).
14462 find(dwarf_dieoffset(die));
14463 if (i != rdr.die_wip_function_types_map(source).end())
14464 rdr.die_wip_function_types_map(source).erase(i);
14467 maybe_canonicalize_type(result, rdr);
14494 build_subrange_type(reader& rdr,
14495 const Dwarf_Die* die,
14496 size_t where_offset,
14497 bool associate_type_to_die)
14504 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
14505 if (tag != DW_TAG_subrange_type)
14508 string name = die_name(die);
14511 Dwarf_Die underlying_type_die;
14512 type_base_sptr underlying_type;
14514 bool is_signed =
false;
14515 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14517 is_type(build_ir_node_from_die(rdr,
14518 &underlying_type_die,
14522 if (underlying_type)
14525 if (die_unsigned_constant_attribute (&underlying_type_die,
14528 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14532 array_type_def::subrange_type::bound_value lower_bound =
14533 get_default_array_lower_bound(language);
14534 array_type_def::subrange_type::bound_value upper_bound;
14535 uint64_t count = 0;
14536 bool is_non_finite =
false;
14537 bool non_zero_count_present =
false;
14548 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14550 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14551 is_signed, upper_bound);
14552 if (!found_upper_bound)
14553 found_upper_bound = subrange_die_indirect_bound_value(die,
14558 if (!found_upper_bound)
14571 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14579 non_zero_count_present =
true;
14584 int64_t u = lower_bound.get_signed_value() + count;
14586 upper_bound = u - 1;
14589 if (!non_zero_count_present)
14593 is_non_finite =
true;
14596 if (UINT64_MAX == upper_bound.get_unsigned_value())
14599 is_non_finite =
true;
14602 (
new array_type_def::subrange_type(rdr.env(),
14607 result->is_non_finite(is_non_finite);
14609 if (underlying_type)
14610 result->set_underlying_type(underlying_type);
14614 || (result->get_length() ==
14615 (uint64_t) (result->get_upper_bound()
14616 - result->get_lower_bound() + 1)));
14618 if (associate_type_to_die)
14619 rdr.associate_die_to_type(die, result, where_offset);
14641 build_subranges_from_array_type_die(reader& rdr,
14642 const Dwarf_Die* die,
14644 size_t where_offset,
14645 bool associate_type_to_die)
14649 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
14653 int child_tag = dwarf_tag(&child);
14654 if (child_tag == DW_TAG_subrange_type)
14657 if (associate_type_to_die)
14663 build_ir_node_from_die(rdr, &child,
14672 s = build_subrange_type(rdr, &child,
14676 subranges.push_back(s);
14679 while (dwarf_siblingof(&child, &child) == 0);
14700 build_array_type(reader& rdr,
14702 bool called_from_public_decl,
14703 size_t where_offset)
14710 unsigned tag = dwarf_tag(die);
14711 if (tag != DW_TAG_array_type)
14714 decl_base_sptr type_decl;
14715 Dwarf_Die type_die;
14717 if (die_die_attribute(die, DW_AT_type, type_die))
14718 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14719 called_from_public_decl,
14726 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14733 type_base_sptr type =
is_type(type_decl);
14738 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14740 result.reset(
new array_type_def(type, subranges, location()));
14762 build_typedef_type(reader& rdr,
14764 bool called_from_public_decl,
14765 size_t where_offset)
14772 unsigned tag = dwarf_tag(die);
14773 if (tag != DW_TAG_typedef)
14776 string name, linkage_name;
14778 die_loc_and_name(rdr, die, loc, name, linkage_name);
14780 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14786 type_base_sptr utype;
14787 Dwarf_Die underlying_type_die;
14788 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14791 utype = rdr.env().get_void_type();
14795 is_type(build_ir_node_from_die(rdr,
14796 &underlying_type_die,
14797 called_from_public_decl,
14803 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
14810 decl_base_sptr decl =
is_decl(utype);
14812 decl->set_naming_typedef(result);
14814 rdr.maybe_schedule_declaration_only_class_for_resolution
14817 rdr.maybe_schedule_declaration_only_enum_for_resolution
14822 rdr.associate_die_to_type(die, result, where_offset);
14859 build_or_get_var_decl_if_not_suppressed(reader& rdr,
14862 size_t where_offset,
14863 bool is_declaration_only,
14865 bool is_required_decl_spec)
14868 if (variable_is_suppressed(rdr, scope, die,
14869 is_declaration_only,
14870 is_required_decl_spec))
14875 string var_name = die_name(die);
14876 if (!var_name.empty())
14877 if ((var = class_type->find_data_member(var_name)))
14880 var = build_var_decl(rdr, die, where_offset, result);
14903 build_var_decl(reader& rdr,
14905 size_t where_offset,
14911 int tag = dwarf_tag(die);
14912 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
14914 if (!die_is_public_decl(die))
14917 type_base_sptr type;
14918 Dwarf_Die type_die;
14919 if (die_die_attribute(die, DW_AT_type, type_die))
14921 decl_base_sptr ty =
14922 is_decl(build_ir_node_from_die(rdr, &type_die,
14931 if (!type && !result)
14934 string name, linkage_name;
14936 die_loc_and_name(rdr, die, loc, name, linkage_name);
14939 result.reset(
new var_decl(name, type, loc, linkage_name));
14945 if (!linkage_name.empty())
14946 result->set_linkage_name(linkage_name);
14949 result->set_type(type);
14955 if (!result->get_symbol())
14958 Dwarf_Addr var_addr;
14960 if (rdr.get_variable_address(die, var_addr))
14963 update_main_symbol(var_addr,
14964 result->get_linkage_name().empty()
14965 ? result->get_name()
14966 : result->get_linkage_name());
14967 var_sym = rdr.variable_symbol_is_exported(var_addr);
14972 result->set_symbol(var_sym);
14975 string linkage_name = result->get_linkage_name();
14976 if (linkage_name.empty()
14977 || !var_sym->get_alias_from_name(linkage_name))
14978 result->set_linkage_name(var_sym->get_name());
14979 result->set_is_in_public_symbol_table(
true);
14982 if (!var_sym && rdr.is_decl_die_with_undefined_symbol(die))
14986 string n = result->get_linkage_name();
14988 n = result->get_name();
14989 var_sym = rdr.symtab()->lookup_undefined_variable_symbol(n);
14992 result->set_symbol(var_sym);
14993 result->set_is_in_public_symbol_table(
false);
15020 function_is_suppressed(
const reader& rdr,
15021 const scope_decl* scope,
15022 Dwarf_Die *function_die,
15023 bool is_declaration_only)
15025 if (function_die == 0
15026 || dwarf_tag(function_die) != DW_TAG_subprogram)
15029 string fname = die_string_attribute(function_die, DW_AT_name);
15030 string flinkage_name = die_linkage_name(function_die);
15031 if (flinkage_name.empty() && die_is_in_c(function_die))
15032 flinkage_name = fname;
15042 && (!is_declaration_only || rdr.drop_undefined_syms()))
15044 Dwarf_Addr fn_addr;
15045 if (!rdr.get_function_address(function_die, fn_addr))
15049 rdr.function_symbol_is_exported(fn_addr);
15052 if (!symbol->is_suppressed())
15059 if (symbol->has_aliases())
15061 !a->is_main_symbol(); a = a->get_next_alias())
15062 if (!a->is_suppressed())
15111 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
15114 size_t where_offset,
15115 bool is_declaration_only,
15119 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
15122 string name = die_name(fn_die);
15123 string linkage_name = die_linkage_name(fn_die);
15124 bool is_dtor = !name.empty() && name[0]==
'~';
15125 bool is_virtual =
false;
15128 Dwarf_Attribute attr;
15129 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
15130 DW_AT_vtable_elem_location,
15142 if (!result && (!(is_dtor && is_virtual)))
15145 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
15146 rdr.associate_die_to_decl(fn_die, fn,
true);
15147 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
15155 string linkage_name = die_linkage_name(fn_die);
15156 fn = klass->find_member_function_sptr(linkage_name);
15163 if (!fn || !fn->get_symbol())
15170 fn = build_function_decl(rdr, fn_die, where_offset, result);
15195 variable_is_suppressed(
const reader& rdr,
15196 const scope_decl* scope,
15197 Dwarf_Die *variable_die,
15198 bool is_declaration_only,
15199 bool is_required_decl_spec)
15201 if (variable_die == 0
15202 || (dwarf_tag(variable_die) != DW_TAG_variable
15203 && dwarf_tag(variable_die) != DW_TAG_member))
15206 string name = die_string_attribute(variable_die, DW_AT_name);
15207 string linkage_name = die_linkage_name(variable_die);
15208 if (linkage_name.empty() && die_is_in_c(variable_die))
15209 linkage_name = name;
15218 && !is_required_decl_spec
15222 && (!is_declaration_only || !rdr.load_undefined_interfaces()))
15224 Dwarf_Addr var_addr = 0;
15225 if (!rdr.get_variable_address(variable_die, var_addr))
15229 rdr.variable_symbol_is_exported(var_addr);
15232 if (!symbol->is_suppressed())
15239 if (symbol->has_aliases())
15241 !a->is_main_symbol(); a = a->get_next_alias())
15242 if (!a->is_suppressed())
15271 type_is_suppressed(
const reader& rdr,
15272 const scope_decl* scope,
15273 Dwarf_Die *type_die,
15274 bool &type_is_opaque)
15277 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
15278 && dwarf_tag(type_die) != DW_TAG_class_type
15279 && dwarf_tag(type_die) != DW_TAG_structure_type
15280 && dwarf_tag(type_die) != DW_TAG_union_type))
15283 string type_name, linkage_name;
15284 location type_location;
15285 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15309 type_is_suppressed(
const reader& rdr,
15310 const scope_decl* scope,
15311 Dwarf_Die *type_die)
15313 bool type_is_opaque =
false;
15314 return type_is_suppressed(rdr, scope, type_die, type_is_opaque);
15338 get_opaque_version_of_type(reader &rdr,
15340 Dwarf_Die *type_die,
15341 size_t where_offset)
15348 unsigned tag = dwarf_tag(type_die);
15349 if (tag != DW_TAG_class_type
15350 && tag != DW_TAG_structure_type
15351 && tag != DW_TAG_union_type
15352 && tag != DW_TAG_enumeration_type)
15355 string type_name, linkage_name;
15356 location type_location;
15357 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15366 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15368 string_classes_or_unions_map::const_iterator i =
15369 rdr.declaration_only_classes().find(qualified_name);
15370 if (i != rdr.declaration_only_classes().end())
15371 result = i->second.back();
15382 tag == DW_TAG_structure_type,
15384 decl_base::VISIBILITY_DEFAULT));
15385 klass->set_is_declaration_only(
true);
15386 klass->set_is_artificial(die_is_artificial(type_die));
15388 rdr.associate_die_to_type(type_die, klass, where_offset);
15389 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15394 if (tag == DW_TAG_enumeration_type)
15396 string_enums_map::const_iterator i =
15397 rdr.declaration_only_enums().find(qualified_name);
15398 if (i != rdr.declaration_only_enums().end())
15399 result = i->second.back();
15404 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15407 build_enum_underlying_type(rdr, type_name, size,
15415 enum_type->set_is_artificial(die_is_artificial(type_die));
15417 result = enum_type;
15440 elf_symbol::FUNC_TYPE,
15441 elf_symbol::GLOBAL_BINDING,
15445 elf_symbol::DEFAULT_VISIBILITY);
15463 build_function_decl(reader& rdr,
15465 size_t where_offset,
15471 int tag = dwarf_tag(die);
15472 ABG_ASSERT(tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine);
15474 if (!die_is_public_decl(die))
15480 string fname, flinkage_name;
15482 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15484 size_t is_inline = die_is_declared_inline(die);
15485 class_or_union_sptr is_method =
15498 if (!flinkage_name.empty()
15499 && result->get_linkage_name() != flinkage_name)
15500 result->set_linkage_name(flinkage_name);
15502 if (!result->get_location())
15503 result->set_location(floc);
15504 result->is_declared_inline(is_inline);
15513 maybe_canonicalize_type(fn_type, rdr);
15515 result.reset(is_method
15516 ?
new method_decl(fname, fn_type,
15519 :
new function_decl(fname, fn_type,
15526 if (!result->get_symbol())
15529 Dwarf_Addr fn_addr;
15530 if (rdr.get_function_address(die, fn_addr))
15533 update_main_symbol(fn_addr,
15534 result->get_linkage_name().empty()
15535 ? result->get_name()
15536 : result->get_linkage_name());
15537 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15540 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15542 result->set_symbol(fn_sym);
15543 string linkage_name = result->get_linkage_name();
15544 if (linkage_name.empty())
15545 result->set_linkage_name(fn_sym->get_name());
15546 result->set_is_in_public_symbol_table(
true);
15549 if (!fn_sym && rdr.is_decl_die_with_undefined_symbol(die))
15553 string n = result->get_linkage_name();
15555 n = result->get_name();
15556 fn_sym = rdr.symtab()->lookup_undefined_function_symbol(n);
15559 result->set_symbol(fn_sym);
15560 result->set_is_in_public_symbol_table(
false);
15565 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15567 size_t die_offset = dwarf_dieoffset(die);
15572 && !result->get_linkage_name().empty())
15578 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15597 maybe_canonicalize_type(
const type_base_sptr& t,
15610 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15620 rdr.schedule_type_for_late_canonicalization(t);
15622 rdr.schedule_type_for_late_canonicalization(t);
15633 maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15636 if (
is_type(member_type_declaration)
15639 class_or_union* scope =
15645 if (!cl->is_struct())
15646 access = private_access;
15648 die_access_specifier(die, access);
15668 const Dwarf_Die *fn_die)
15670 if (!fn || fn->get_scope())
15674 !die_is_virtual(fn_die)
15676 && !fn->get_symbol())
15721 build_ir_node_from_die(reader& rdr,
15724 bool called_from_public_decl,
15725 size_t where_offset,
15726 bool is_declaration_only,
15727 bool is_required_decl_spec)
15731 if (!die || !scope)
15734 int tag = dwarf_tag(die);
15736 if (!called_from_public_decl)
15738 if (rdr.load_all_types() && die_is_type(die))
15742 else if (tag != DW_TAG_subprogram
15743 && tag != DW_TAG_variable
15744 && tag != DW_TAG_member
15745 && tag != DW_TAG_namespace)
15749 const die_source source_of_die = rdr.get_die_source(die);
15751 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15754 if (rdr.load_all_types())
15755 if (called_from_public_decl)
15756 if (type_base_sptr t =
is_type(result))
15757 if (corpus *abi_corpus = scope->get_corpus())
15758 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15767 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15772 case DW_TAG_base_type:
15781 case DW_TAG_typedef:
15784 called_from_public_decl,
15790 maybe_set_member_type_access_specifier(
is_decl(result), die);
15791 maybe_canonicalize_type(t, rdr);
15796 case DW_TAG_pointer_type:
15799 build_pointer_type_def(rdr, die,
15800 called_from_public_decl,
15807 maybe_canonicalize_type(p, rdr);
15812 case DW_TAG_reference_type:
15813 case DW_TAG_rvalue_reference_type:
15816 build_reference_type(rdr, die,
15817 called_from_public_decl,
15824 rdr.associate_die_to_type(die, r, where_offset);
15825 maybe_canonicalize_type(r, rdr);
15830 case DW_TAG_ptr_to_member_type:
15833 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
15839 maybe_canonicalize_type(p, rdr);
15844 case DW_TAG_const_type:
15845 case DW_TAG_volatile_type:
15846 case DW_TAG_restrict_type:
15849 build_qualified_type(rdr, die,
15850 called_from_public_decl,
15861 type_base_sptr ty =
is_type(d);
15865 rdr.associate_die_to_type(die, ty, where_offset);
15868 maybe_canonicalize_type(
is_type(result), rdr);
15873 case DW_TAG_enumeration_type:
15875 bool type_is_opaque =
false;
15876 bool type_suppressed =
15877 type_is_suppressed(rdr, scope, die, type_is_opaque);
15878 if (type_suppressed && type_is_opaque)
15886 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15887 maybe_canonicalize_type(
is_type(result), rdr);
15889 else if (!type_suppressed)
15893 is_declaration_only);
15897 maybe_set_member_type_access_specifier(
is_decl(result), die);
15898 maybe_canonicalize_type(
is_type(result), rdr);
15904 case DW_TAG_class_type:
15905 case DW_TAG_structure_type:
15907 bool type_is_opaque =
false;
15908 bool type_suppressed=
15909 type_is_suppressed(rdr, scope, die, type_is_opaque);
15911 if (type_suppressed && type_is_opaque)
15919 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15920 maybe_canonicalize_type(
is_type(result), rdr);
15922 else if (!type_suppressed)
15924 Dwarf_Die spec_die;
15927 if (die_die_attribute(die, DW_AT_specification, spec_die))
15930 get_scope_for_die(rdr, &spec_die,
15931 called_from_public_decl,
15934 decl_base_sptr cl =
15935 is_decl(build_ir_node_from_die(rdr, &spec_die,
15937 called_from_public_decl,
15939 is_declaration_only,
15942 klass = dynamic_pointer_cast<class_decl>(cl);
15946 add_or_update_class_type(rdr, die,
15948 tag == DW_TAG_structure_type,
15950 called_from_public_decl,
15952 is_declaration_only);
15956 add_or_update_class_type(rdr, die, scope,
15957 tag == DW_TAG_structure_type,
15959 called_from_public_decl,
15961 is_declaration_only);
15965 maybe_set_member_type_access_specifier(klass, die);
15966 maybe_canonicalize_type(klass, rdr);
15971 case DW_TAG_union_type:
15972 if (!type_is_suppressed(rdr, scope, die))
15974 union_decl_sptr union_type =
15975 add_or_update_union_type(rdr, die, scope,
15977 called_from_public_decl,
15979 is_declaration_only);
15982 maybe_set_member_type_access_specifier(union_type, die);
15983 maybe_canonicalize_type(union_type, rdr);
15985 result = union_type;
15988 case DW_TAG_string_type:
15990 case DW_TAG_subroutine_type:
15998 result->set_is_artificial(
false);
15999 maybe_canonicalize_type(f, rdr);
16003 case DW_TAG_array_type:
16007 called_from_public_decl,
16013 rdr.associate_die_to_type(die, a, where_offset);
16014 maybe_canonicalize_type(a, rdr);
16018 case DW_TAG_subrange_type:
16024 build_subrange_type(rdr, die, where_offset);
16029 rdr.associate_die_to_type(die, s, where_offset);
16030 maybe_canonicalize_type(s, rdr);
16034 case DW_TAG_packed_type:
16036 case DW_TAG_set_type:
16038 case DW_TAG_file_type:
16040 case DW_TAG_thrown_type:
16042 case DW_TAG_interface_type:
16044 case DW_TAG_unspecified_type:
16046 case DW_TAG_shared_type:
16049 case DW_TAG_compile_unit:
16054 case DW_TAG_namespace:
16055 case DW_TAG_module:
16056 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
16059 case DW_TAG_variable:
16060 case DW_TAG_member:
16062 Dwarf_Die spec_die;
16063 bool var_is_cloned =
false;
16065 if (tag == DW_TAG_member)
16068 if (die_die_attribute(die, DW_AT_specification, spec_die,
false)
16069 || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
16073 get_scope_for_die(rdr, &spec_die,
16075 die_is_effectively_public_decl(rdr, die),
16080 is_decl(build_ir_node_from_die(rdr, &spec_die,
16082 called_from_public_decl,
16084 is_declaration_only,
16089 dynamic_pointer_cast<var_decl>(d);
16092 m = build_var_decl(rdr, die, where_offset, m);
16096 rdr.associate_die_to_decl(die, m, where_offset,
16102 rdr.var_decls_to_re_add_to_tree().push_back(m);
16105 rdr.add_var_to_exported_or_undefined_decls(m.get());
16111 build_or_get_var_decl_if_not_suppressed(rdr, scope, die,
16113 is_declaration_only,
16115 is_required_decl_spec))
16119 v = dynamic_pointer_cast<var_decl>(result);
16122 rdr.var_decls_to_re_add_to_tree().push_back(v);
16123 rdr.add_var_to_exported_or_undefined_decls(v.get());
16128 case DW_TAG_subprogram:
16129 case DW_TAG_inlined_subroutine:
16131 if (die_is_artificial(die))
16134 Dwarf_Die abstract_origin_die;
16135 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
16136 abstract_origin_die,
16140 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
16142 scope_decl* interface_scope = scope ? scope : s.get();
16145 string linkage_name = die_linkage_name(die);
16146 string spec_linkage_name;
16153 if (!linkage_name.empty())
16156 class_scope->find_member_function_sptr(linkage_name)))
16161 spec_linkage_name = existing_fn->get_linkage_name();
16162 if (has_abstract_origin
16163 && !spec_linkage_name.empty()
16164 && linkage_name != spec_linkage_name)
16171 existing_fn = existing_fn->clone();
16177 rdr.scope_stack().push(interface_scope);
16184 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
16186 is_declaration_only,
16189 if (result && !existing_fn)
16195 && !is_required_decl_spec)
16211 sptr_utils::noop_deleter());
16213 finish_member_function_reading(die, fn, klass, rdr);
16224 rdr.add_fn_to_exported_or_undefined_decls(fn.get());
16225 rdr.associate_die_to_decl(die, fn, where_offset,
16227 maybe_canonicalize_type(fn->get_type(), rdr);
16230 rdr.scope_stack().pop();
16234 case DW_TAG_formal_parameter:
16239 case DW_TAG_constant:
16241 case DW_TAG_enumerator:
16244 case DW_TAG_partial_unit:
16245 case DW_TAG_imported_unit:
16252 case DW_TAG_dwarf_procedure:
16253 case DW_TAG_imported_declaration:
16254 case DW_TAG_entry_point:
16256 case DW_TAG_lexical_block:
16257 case DW_TAG_unspecified_parameters:
16258 case DW_TAG_variant:
16259 case DW_TAG_common_block:
16260 case DW_TAG_common_inclusion:
16261 case DW_TAG_inheritance:
16262 case DW_TAG_with_stmt:
16263 case DW_TAG_access_declaration:
16264 case DW_TAG_catch_block:
16265 case DW_TAG_friend:
16266 case DW_TAG_namelist:
16267 case DW_TAG_namelist_item:
16268 case DW_TAG_template_type_parameter:
16269 case DW_TAG_template_value_parameter:
16270 case DW_TAG_try_block:
16271 case DW_TAG_variant_part:
16272 case DW_TAG_imported_module:
16273 case DW_TAG_condition:
16274 case DW_TAG_type_unit:
16275 case DW_TAG_template_alias:
16276 case DW_TAG_lo_user:
16277 case DW_TAG_MIPS_loop:
16278 case DW_TAG_format_label:
16279 case DW_TAG_function_template:
16280 case DW_TAG_class_template:
16281 case DW_TAG_GNU_BINCL:
16282 case DW_TAG_GNU_EINCL:
16283 case DW_TAG_GNU_template_template_param:
16284 case DW_TAG_GNU_template_parameter_pack:
16285 case DW_TAG_GNU_formal_parameter_pack:
16286 case DW_TAG_GNU_call_site:
16287 case DW_TAG_GNU_call_site_parameter:
16288 case DW_TAG_hi_user:
16293 if (result && tag != DW_TAG_subroutine_type)
16294 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
16298 if (rdr.load_all_types())
16299 if (called_from_public_decl)
16300 if (type_base_sptr t =
is_type(result))
16301 if (corpus *abi_corpus = scope->get_corpus())
16302 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
16312 static decl_base_sptr
16313 build_ir_node_for_void_type(reader& rdr)
16315 const environment& env = rdr.env();
16317 type_base_sptr t = env.get_void_type();
16321 return type_declaration;
16336 build_ir_node_for_void_pointer_type(reader& rdr)
16338 const environment& env = rdr.env();
16340 type_base_sptr t = env.get_void_pointer_type();
16344 return type_declaration;
16352 static decl_base_sptr
16353 build_ir_node_for_variadic_parameter_type(reader &rdr)
16356 const environment& env = rdr.env();
16358 type_base_sptr t = env.get_variadic_parameter_type();
16362 return type_declaration;
16388 build_ir_node_from_die(reader& rdr,
16390 bool called_from_public_decl,
16391 size_t where_offset)
16394 return decl_base_sptr();
16404 bool consider_as_called_from_public_decl =
16405 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
16407 consider_as_called_from_public_decl,
16409 return build_ir_node_from_die(rdr, die, scope.get(),
16410 called_from_public_decl,
16411 where_offset,
true);
16445 elf_based_reader_sptr
16447 const vector<char**>& debug_info_root_paths,
16449 bool load_all_types,
16450 bool linux_kernel_mode)
16453 reader_sptr r = reader::create(elf_path,
16454 debug_info_root_paths,
16457 linux_kernel_mode);
16458 return static_pointer_cast<elf_based_reader>(r);
16497 const std::string& elf_path,
16498 const vector<char**>&debug_info_root_path,
16499 bool read_all_types,
16500 bool linux_kernel_mode)
16502 reader& r =
dynamic_cast<reader&
>(rdr);
16503 r.initialize(elf_path, debug_info_root_path,
16504 read_all_types, linux_kernel_mode);
16541 const vector<char**>& debug_info_root_paths,
16543 bool load_all_types,
16546 elf_based_reader_sptr rdr =
16547 dwarf::reader::create(elf_path, debug_info_root_paths,
16551 return rdr->read_corpus(status);
16572 const string& elf_path,
16573 const string& symbol_name,
16575 vector<elf_symbol_sptr>& syms)
16578 if (elf_version(EV_CURRENT) == EV_NONE)
16581 int fd = open(elf_path.c_str(), O_RDONLY);
16589 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
16617 const string& path,
16618 const string& symname,
16619 vector<elf_symbol_sptr>& syms)
16621 if (elf_version(EV_CURRENT) == EV_NONE)
16624 int fd = open(path.c_str(), O_RDONLY);
16632 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one.
bool architecture_is_big_endian(Elf *elf_handle)
Test if the endianness of the current binary is Big Endian.
bool get_binary_load_address(Elf *elf_handle, GElf_Addr &load_address)
Get the address at which a given binary is loaded in memory.
bool get_version_for_symbol(Elf *elf_handle, size_t symbol_index, bool get_def_version, elf_symbol::version &version)
Return the version for a symbol that is at a given index in its SHT_SYMTAB section.
elf_symbol::binding stb_to_elf_symbol_binding(unsigned char stb)
Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND macros) into an elf_symbol::binding va...
elf_symbol::visibility stv_to_elf_symbol_visibility(unsigned char stv)
Convert an ELF symbol visiblity given by the symbols ->st_other data member as returned by the GELF_S...
bool find_symbol_table_section_index(Elf *elf_handle, size_t &symtab_index)
Find the index (in the section headers table) of the symbol table section.
elf_symbol::type stt_to_elf_symbol_type(unsigned char stt)
Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE macros) into an elf_symbol::type value.
hash_table_kind find_hash_table_section_index(Elf *elf_handle, size_t &ht_section_index, size_t &symtab_section_index)
Get the offset offset of the hash table section.
This contains a set of ELF utilities used by the dwarf reader.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
The common interface of readers based on ELF.
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
status
The status of the fe_iface::read_corpus call.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
scope_decl * get_scope() const
Return the type containing the current decl, if any.
The abstraction of the version of an ELF symbol.
binding
The binding of a symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
The internal representation of an integral type.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
The source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
language
The language of the translation unit.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
unordered_map< std::pair< offset_type, offset_type >, offset_pair_set_type, offset_pair_hash > offset_pair_set_map_type
A convenience typedef for an unordered_map that associates a pair of offset_type to a set of pairs of...
unordered_map< Dwarf_Off, translation_unit_sptr > die_tu_map_type
Convenience typedef for a map which key is the offset of a DW_TAG_compile_unit and the value is the c...
bool lookup_symbol_from_elf(const environment &env, const string &elf_path, const string &symbol_name, bool demangle, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of a given elf file and see if we find a given symbol.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< char ** > &debug_info_root_path, bool read_all_types, bool linux_kernel_mode)
Re-initialize a reader so that it can re-used to read another binary.
unordered_map< string, classes_type > string_classes_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
shared_ptr< addr_elf_symbol_sptr_map_type > addr_elf_symbol_sptr_map_sptr
Convenience typedef for a shared pointer to an addr_elf_symbol_sptr_map_type.
unordered_map< Dwarf_Off, class_or_union_sptr > die_class_or_union_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
unordered_map< Dwarf_Off, function_type_sptr > die_function_type_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< Dwarf_Off, interned_string > die_istring_map_type
Convenience typedef for a map which key is the offset of a DIE and the value is the corresponding qua...
unordered_map< Dwarf_Off, function_decl_sptr > die_function_decl_map_type
Convenience typedef for a map which key the offset of a dwarf die and which value is the correspondin...
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
unordered_map< Dwarf_Off, type_or_decl_base_sptr > die_artefact_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_vector_type, offset_pair_hash > offset_pair_vect_map_type
A convenience typedef for an unordered map that associates a pair of offset_type to a vector of pairs...
unordered_map< interned_string, function_type_sptr, hash_interned_string > istring_fn_type_map_type
Convenience typedef for a map that associates an interned_string to a function_type_sptr.
unordered_map< Dwarf_Off, class_decl_sptr > die_class_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
unordered_map< string, classes_or_unions_type > string_classes_or_unions_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
unordered_map< Dwarf_Off, Dwarf_Off > offset_offset_map_type
Convenience typedef for a map which key is a dwarf offset. The value is also a dwarf offset.
unordered_set< std::pair< offset_type, offset_type >, offset_pair_hash > offset_pair_set_type
A convenience typedef for an unordered set of pairs of offset_type.
unordered_map< string, enums_type > string_enums_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
bool lookup_public_function_symbol_from_elf(environment &env, const string &path, const string &symname, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of an elf file to see if a public function of a given name is found.
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, bool linux_kernel_mode)
Create a dwarf::reader.
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section,...
unordered_map< interned_string, dwarf_offsets_type, hash_interned_string > istring_dwarf_offsets_map_type
Convenience typedef for a map which is an interned_string and which value is a vector of offsets.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
corpus_sptr read_corpus_from_elf(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, fe_iface::status &status)
Read all abigail::translation_unit possible from the debug info accessible from an elf file,...
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_opaque, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
Toplevel namespace for libabigail.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
A functor to hash instances of interned_string.