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
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,
253 typedef unordered_map<interned_string,
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,
639 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type&,
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))
846 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
847 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
849 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
850 sym_size = symbol.st_size;
851 elf_symbol::version ver;
852 if (get_version_for_symbol(elf_handle, symbol_index,
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))
1137 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
1138 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
1140 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
1142 if (get_version_for_symbol(elf_handle, i,
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))
1289 stt_to_elf_symbol_type(GELF_ST_TYPE(sym->st_info));
1291 stb_to_elf_symbol_binding(GELF_ST_BIND(sym->st_info));
1293 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(sym->st_other));
1294 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1295 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1297 if (get_version_for_symbol(elf_handle, i,
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;
1355 ht_kind = find_hash_table_section_index(elf_handle,
1357 symbol_table_index);
1359 if (ht_kind == NO_HASH_TABLE_KIND)
1361 if (!find_symbol_table_section_index(elf_handle, symbol_table_index))
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_;
1935 mutable istring_fn_type_map_type per_tu_repr_to_fn_type_maps_;
1938 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1940 dwarf_offset_pair_hash> die_comparison_results_;
1942 mutable offset_pair_set_type propagated_types_;
1943 die_class_or_union_map_type die_wip_classes_map_;
1944 die_class_or_union_map_type alternate_die_wip_classes_map_;
1945 die_class_or_union_map_type type_unit_die_wip_classes_map_;
1946 die_function_type_map_type die_wip_function_types_map_;
1947 die_function_type_map_type alternate_die_wip_function_types_map_;
1948 die_function_type_map_type type_unit_die_wip_function_types_map_;
1949 die_function_decl_map_type die_function_with_no_symbol_map_;
1950 vector<type_base_sptr> types_to_canonicalize_;
1951 string_classes_or_unions_map decl_only_classes_map_;
1952 string_enums_map decl_only_enums_map_;
1953 die_tu_map_type die_tu_map_;
1956 scope_stack_type scope_stack_;
1957 offset_offset_map_type primary_die_parent_map_;
1967 offset_offset_map_type alternate_die_parent_map_;
1968 offset_offset_map_type type_section_die_parent_map_;
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
2616 offset_offset_map_type &canonical_dies =
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,
2645 offset_offset_map_type& canonical_dies,
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,
2677 offset_offset_map_type& canonical_dies,
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);
2709 dwarf_offsets_type offsets;
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);
2765 offset_offset_map_type &canonical_dies =
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);
2857 offset_offset_map_type &canonical_dies =
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);
2900 dwarf_offsets_type offsets;
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);
3067 die_artefact_map_type& m =
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)
3129 die_istring_map_type& map =
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(
"");
3192 die_istring_map_type& map =
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
3247 die_istring_map_type& map =
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
3284 die_istring_map_type& map =
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))
3356 const die_artefact_map_type& m =
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
3393 const die_artefact_map_type& m =
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_;}
3503 istring_fn_type_map_type&
3504 per_tu_repr_to_fn_type_maps()
3505 {
return per_tu_repr_to_fn_type_maps_;}
3512 const istring_fn_type_map_type&
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,
3525 const function_type_sptr &fn_type)
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())
3574 set_canonical_die_offset(offset_offset_map_type &canonical_dies,
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
3599 offset_offset_map_type &canonical_dies =
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,
3644 get_canonical_die_offset(offset_offset_map_type &canonical_dies,
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
3669 offset_offset_map_type &canonical_dies =
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
3695 offset_offset_map_type &canonical_dies =
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,
3727 die_artefact_map_type& m =
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;
3771 const die_artefact_map_type& m =
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();
3784 const die_class_or_union_map_type& m = die_wip_classes_map(source);
3785 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3794 const die_function_type_map_type& m =
3795 die_wip_function_types_map(source);
3796 die_function_type_map_type::const_iterator i = m.find(die_offset);
3813 const die_class_or_union_map_type&
3815 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3825 die_class_or_union_map_type&
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_;
3850 const die_function_type_map_type&
3851 die_wip_function_types_map(
die_source source)
const
3852 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3861 die_function_type_map_type&
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_;
3886 die_function_decl_map_type&
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();
3988 const string_classes_or_unions_map&
3989 declaration_only_classes()
const
3990 {
return decl_only_classes_map_;}
3999 string_classes_or_unions_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";
4258 const string_enums_map&
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();
4541 die_function_decl_map_type &fns_with_no_symbol =
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 <<
"%)";
4705 const die_tu_map_type&
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_;
4761 const offset_offset_map_type&
4763 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4771 offset_offset_map_type&
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_;
4789 const offset_offset_map_type&
4790 type_section_die_parent_map()
const
4791 {
return type_section_die_parent_map_;}
4793 offset_offset_map_type&
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_;}
4835 const scope_stack_type&
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;
4948 ABG_ASSERT(get_binary_load_address(dwarf_elf_handle(),
4949 dwarf_elf_load_address));
4950 ABG_ASSERT(get_binary_load_address(elf_handle(),
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,
5285 imported_unit_points_type & imported_units)
5290 offset_offset_map_type& parent_of = die_parent_map(source);
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()),
5433 imported_unit_points_type& imported_units =
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()),
5456 imported_unit_points_type& imported_units =
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()),
5483 imported_unit_points_type& imported_units =
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
5507 offset_pair_set_type set_;
5510 offset_pair_vector_type vect_;
5513 offset_pair_vect_map_type redundant_types_;
5516 offset_pair_vect_map_type dependant_types_;
5518 offset_pairs_stack_type(
const reader& rdr)
5527 add(
const offset_pair_type& p)
5540 erase(
const offset_pair_type& p)
5544 offset_pair_vector_type::iterator i;
5546 for (i = vect_.begin();i < vect_.end(); ++i)
5550 if (i != vect_.end())
5567 contains(
const offset_pair_type &p)
const
5569 if (set_.find(p) == set_.end())
5593 get_pairs_that_depend_on(
const offset_pair_type& p,
5594 offset_pair_vector_type& pairs)
const
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);
5630 record_dependant_types(
const offset_pair_type& p,
5631 const offset_pair_vector_type& dependant_types)
5633 for (
auto type_pair : dependant_types)
5634 dependant_types_[type_pair].push_back(p);
5642 record_redundant_type_die_pair(
const offset_pair_type& p)
5644 offset_pair_vector_type dependant_types;
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);
5670 is_redundant(
const offset_pair_type& p)
5672 auto i = redundant_types_.find(p);
5673 if (i != redundant_types_.end())
5684 depends_on_redundant_types(
const offset_pair_type& p)
5686 auto i = dependant_types_.find(p);
5687 if (i == dependant_types_.end())
5704 erase_redundant_type_pair_entry(
const offset_pair_type& p,
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);
5752 confirm_canonical_propagated_type(
const offset_pair_type& p)
5753 {erase_redundant_type_pair_entry(p,
true);}
5763 cancel_canonical_propagated_type(
const offset_pair_type& p)
5765 offset_pair_set_type dependant_types;
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_++;
5824 get_dependant_types(
const offset_pair_type& p,
5825 offset_pair_set_type& result,
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,
6906 const offset_pair_type& p,
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,
6935 const offset_pair_type& p,
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,
6964 const offset_pair_type& p,
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()))
9080 bool is_big_endian = architecture_is_big_endian(rdr.elf_handle());
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;
9240 o << base_name << anonymous_type_index;
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,
10759 const offset_pair_type& cur_dies,
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))
10946 offset_pair_type dies_being_compared(l_offset, r_offset);
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());
11673 const imported_unit_points_type& imported_unit_points = iter->second;
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);
11828 const offset_offset_map_type& m = rdr.die_parent_map(source);
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:
12261 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type& p,
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);
12861 die_function_decl_map_type &fns_with_no_symbol =
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);
14256 static function_type_sptr
14257 build_function_type(reader& rdr,
14259 class_or_union_sptr is_method,
14260 size_t where_offset)
14262 function_type_sptr result;
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);
14300 if (odr_is_relevant)
14309 if (function_type_sptr fn_type =
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);
15508 function_type_sptr fn_type(build_function_type(rdr, die, is_method,
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:
15992 function_type_sptr f = build_function_type(rdr, die,
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,
16448 environment& environment,
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);
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,
16542 environment& environment,
16543 bool load_all_types,
16546 elf_based_reader_sptr rdr =
16547 dwarf::reader::create(elf_path, debug_info_root_paths,
16548 environment, load_all_types,
16551 return rdr->read_corpus(status);
16571 lookup_symbol_from_elf(
const environment& env,
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);
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...
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
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...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
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.
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.
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.
visibility
The visibility of the symbol.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
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...
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
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.
The internal representation of an integral type.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
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.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
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...
Utilities to ease the wrapping of C types into std::shared_ptr.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
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...
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
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...
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
A functor to hash instances of interned_string.
status
The status of the fe_iface::read_corpus call.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
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.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
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...
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< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
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.
This contains the declarations for the symtab reader.
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.
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...
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...
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
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...
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
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...
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Toplevel namespace for libabigail.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
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...
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
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.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section, the alternate debug info section or from the type unit section.
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.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
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.
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...
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
type
The type of a symbol.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
The source location of a token.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one...
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
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...
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...
This contains the private implementation of the suppression engine of libabigail. ...
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
The common interface of readers based on ELF.
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...
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
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...
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
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 is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
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_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
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.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
binding
The binding of a symbol.
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.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_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.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
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.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
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...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
language
The language of the translation unit.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
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_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...
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.
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.
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.
This contains a set of ELF utilities used by the dwarf reader.
The abstraction of an interned string.
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.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
The abstraction of the version of an ELF symbol.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
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.
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, reference_type_def, or array_type_def node.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
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.
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...
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...
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.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
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.
access_specifier
Access specifier for class members.
The private data and functions of the abigail::ir::corpus type.
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.
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
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...
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
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...
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
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.
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
CV
Bit field values representing the cv qualifiers of the underlying type.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
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...