14#include "abg-internal.h"
22#include <elfutils/libdwfl.h>
33#include <unordered_map>
34#include <unordered_set>
43ABG_BEGIN_EXPORT_DECLARATIONS
51ABG_END_EXPORT_DECLARATIONS
55#define UINT64_MAX 0xffffffffffffffff
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71using std::unordered_map;
72using std::unordered_set;
79using 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,
138struct 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);}
145typedef 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_);}
191struct 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);
208typedef unordered_set<std::pair<offset_type,
217typedef unordered_map<std::pair<offset_type, offset_type>,
223typedef unordered_map<std::pair<offset_type, offset_type>,
233build_translation_unit_and_add_to_ir(reader& rdr,
238maybe_propagate_canonical_type(
const reader& rdr,
243propagate_canonical_type(
const reader& rdr,
285struct 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);
355typedef unordered_map<Dwarf_Off, imported_unit_points_type>
367operator<(
const imported_unit_point& l,
const imported_unit_point& r)
368{
return l.offset_of_import < r.offset_of_import;}
371get_parent_die(
const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
377get_scope_die(
const reader& rdr,
378 const Dwarf_Die* die,
380 Dwarf_Die& scope_die);
386die_is_in_c(
const Dwarf_Die *die);
389die_is_in_cplus_plus(
const Dwarf_Die *die);
392die_is_in_c_or_cplusplus(
const Dwarf_Die *die);
395die_is_anonymous(
const Dwarf_Die* die);
398die_is_anonymous_data_member(
const Dwarf_Die* die);
401die_is_type(
const Dwarf_Die* die);
404die_is_decl(
const Dwarf_Die* die);
407die_is_declaration_only(Dwarf_Die* die);
410die_is_variable_decl(
const Dwarf_Die *die);
413die_is_function_decl(
const Dwarf_Die *die);
416die_has_size_attribute(
const Dwarf_Die *die);
419die_has_no_child(
const Dwarf_Die *die);
422die_is_namespace(
const Dwarf_Die* die);
425die_is_unspecified(Dwarf_Die* die);
428die_is_void_type(Dwarf_Die* die);
431die_is_pointer_type(
const Dwarf_Die* die);
434pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
437die_is_reference_type(
const Dwarf_Die* die);
440die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
443die_is_pointer_or_reference_type(
const Dwarf_Die* die);
446die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
449die_is_class_type(
const Dwarf_Die* die);
452die_is_qualified_type(
const Dwarf_Die* die);
455die_is_function_type(
const Dwarf_Die *die);
458die_has_object_pointer(
const Dwarf_Die* die,
459 Dwarf_Die& object_pointer);
462die_has_children(
const Dwarf_Die* die);
465fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die);
468member_fn_die_has_this_pointer(
const reader& rdr,
469 const Dwarf_Die* die,
471 Dwarf_Die& class_die,
472 Dwarf_Die& object_pointer_die);
475die_this_pointer_from_object_pointer(Dwarf_Die* die,
476 Dwarf_Die& this_pointer);
479die_this_pointer_is_const(Dwarf_Die* die);
482die_object_pointer_is_for_const_method(Dwarf_Die* die);
485is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
488die_is_at_class_scope(
const reader& rdr,
489 const Dwarf_Die* die,
491 Dwarf_Die& class_scope_die);
493eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
496 bool& is_tls_address);
499dwarf_language_to_tu_language(
size_t l);
502die_unsigned_constant_attribute(
const Dwarf_Die* die,
507die_signed_constant_attribute(
const Dwarf_Die*die,
512die_constant_attribute(
const Dwarf_Die *die,
515 array_type_def::subrange_type::bound_value &value);
518die_member_offset(
const reader& rdr,
519 const Dwarf_Die* die,
523form_is_DW_FORM_strx(
unsigned form);
526form_is_DW_FORM_line_strp(
unsigned form);
529die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
532die_name(
const Dwarf_Die* die);
535die_name_and_linkage_name(
const Dwarf_Die* die,
537 string& linkage_name);
539die_location(
const reader& rdr,
const Dwarf_Die* die);
542die_location_address(Dwarf_Die* die,
544 bool& is_tls_address);
547die_die_attribute(
const Dwarf_Die* die,
550 bool recursively =
true);
553die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
556subrange_die_indirect_bound_value(
const Dwarf_Die *die,
558 array_type_def::subrange_type::bound_value& v,
562subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
564 Dwarf_Die& referenced_subrange);
566get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
569build_internal_anonymous_die_name(
const string &
base_name,
570 size_t anonymous_type_index);
573get_internal_anonymous_die_name(Dwarf_Die *die,
574 size_t anonymous_type_index);
577die_qualified_type_name(
const reader& rdr,
578 const Dwarf_Die* die,
582die_qualified_decl_name(
const reader& rdr,
583 const Dwarf_Die* die,
587die_qualified_name(
const reader& rdr,
588 const Dwarf_Die* die,
592die_qualified_type_name_empty(
const reader& rdr,
593 const Dwarf_Die* die,
size_t where,
594 string &qualified_name);
597die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
598 const Dwarf_Die* die,
601 string &return_type_name,
603 vector<string>& parm_names,
608die_function_signature(
const reader& rdr,
609 const Dwarf_Die *die,
610 size_t where_offset);
613die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
616die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
619die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die);
622die_function_type_is_method_type(
const reader& rdr,
623 const Dwarf_Die *die,
625 Dwarf_Die& object_pointer_die,
626 Dwarf_Die& class_die,
630die_pretty_print_type(reader& rdr,
631 const Dwarf_Die* die,
632 size_t where_offset);
635die_pretty_print_decl(reader& rdr,
636 const Dwarf_Die* die,
637 size_t where_offset);
640die_pretty_print(reader& rdr,
641 const Dwarf_Die* die,
642 size_t where_offset);
645maybe_canonicalize_type(
const type_base_sptr& t,
654 imported_unit_points_type::const_iterator&);
657build_subrange_type(reader& rdr,
658 const Dwarf_Die* die,
660 bool associate_type_to_die =
true);
663build_subranges_from_array_type_die(reader& rdr,
664 const Dwarf_Die* die,
667 bool associate_type_to_die =
true);
670compare_dies(
const reader& rdr,
671 const Dwarf_Die *l,
const Dwarf_Die *r,
672 bool update_canonical_dies_on_the_fly);
675compare_dies_during_canonicalization(reader& rdr,
676 const Dwarf_Die *l,
const Dwarf_Die *r,
677 bool update_canonical_dies_on_the_fly);
680get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
693 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
696 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
699 lang = dwarf_language_to_tu_language(l);
711die_is_in_c(
const Dwarf_Die *die)
714 if (!get_die_language(die, l))
727die_is_in_cplus_plus(
const Dwarf_Die *die)
730 if (!get_die_language(die, l))
743die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
746 if (!get_die_language(die, l))
763compare_symbol_name(
const string& symbol_name,
772 return symbol_name == name;
801lookup_symbol_from_sysv_hash_tab(
const environment& env,
803 const string& sym_name,
805 size_t sym_tab_index,
807 vector<elf_symbol_sptr>& syms_found)
809 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
812 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
815 GElf_Shdr sheader_mem;
816 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
818 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
823 unsigned long hash = elf_hash(sym_name.c_str());
824 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
825 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
826 size_t nb_buckets = ht_data[0];
827 size_t nb_chains = ht_data[1];
835 Elf32_Word* ht_buckets = &ht_data[2];
836 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
839 size_t bucket = hash % nb_buckets;
840 size_t symbol_index = ht_buckets[bucket];
843 const char* sym_name_str;
852 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
853 sym_name_str = elf_strptr(elf_handle,
854 sym_tab_section_header->sh_link,
857 && compare_symbol_name(sym_name_str, sym_name, demangle))
863 sym_size = symbol.st_size;
864 elf_symbol::version ver;
875 symbol.st_shndx != SHN_UNDEF,
876 symbol.st_shndx == SHN_COMMON,
877 ver, sym_visibility);
878 syms_found.push_back(symbol_found);
881 symbol_index = ht_chains[symbol_index];
882 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
893get_elf_class_size_in_bytes(Elf* elf_handle)
899 int c = hdr.e_ident[EI_CLASS];
933bloom_word_at(Elf* elf_handle,
934 Elf32_Word* bloom_filter,
937 Elf64_Xword result = 0;
941 c = h.e_ident[EI_CLASS];
946 result = bloom_filter[index];
950 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
971 size_t first_sym_index;
974 Elf32_Word* bloom_filter;
977 Elf_Scn* sym_tab_section;
978 GElf_Shdr sym_tab_section_header;
1008setup_gnu_ht(Elf* elf_handle,
1010 size_t sym_tab_index,
1013 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1015 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
1017 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
1018 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
1023 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
1024 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
1026 ht.nb_buckets = ht_data[0];
1027 if (ht.nb_buckets == 0)
1031 ht.first_sym_index = ht_data[1];
1034 ht.bf_nwords = ht_data[2];
1036 ht.shift = ht_data[3];
1038 ht.bloom_filter = &ht_data[4];
1043 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
1045 ht.buckets = ht.bloom_filter + ht.bf_size;
1047 ht.chain = ht.buckets + ht.nb_buckets;
1078lookup_symbol_from_gnu_hash_tab(
const environment& env,
1080 const string& sym_name,
1082 size_t sym_tab_index,
1084 vector<elf_symbol_sptr>& syms_found)
1087 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
1093 size_t h1 = elf_gnu_hash(sym_name.c_str());
1094 size_t h2 = h1 >> ht.shift;
1097 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1098 int n = (h1 / c) % ht.bf_nwords;
1104 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1107 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1110 size_t i = ht.buckets[h1 % ht.nb_buckets];
1114 Elf32_Word stop_word, *stop_wordp;
1115 elf_symbol::version ver;
1117 const char* sym_name_str;
1126 for (i = ht.buckets[h1 % ht.nb_buckets],
1127 stop_wordp = &ht.chain[i - ht.first_sym_index];
1130 < ht.chain + (ht.sym_count - ht.first_sym_index));
1133 stop_word = *stop_wordp;
1134 if ((stop_word & ~ 1)!= (h1 & ~1))
1140 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1142 sym_name_str = elf_strptr(elf_handle,
1143 ht.sym_tab_section_header.sh_link,
1146 && compare_symbol_name(sym_name_str, sym_name, demangle))
1164 sym_type, sym_binding,
1165 symbol.st_shndx != SHN_UNDEF,
1166 symbol.st_shndx == SHN_COMMON,
1167 ver, sym_visibility);
1168 syms_found.push_back(symbol_found);
1210lookup_symbol_from_elf_hash_tab(
const environment& env,
1212 hash_table_kind ht_kind,
1214 size_t symtab_index,
1215 const string& symbol_name,
1217 vector<elf_symbol_sptr>& syms_found)
1219 if (elf_handle == 0 || symbol_name.empty())
1222 if (ht_kind == NO_HASH_TABLE_KIND)
1225 if (ht_kind == SYSV_HASH_TABLE_KIND)
1226 return lookup_symbol_from_sysv_hash_tab(env,
1227 elf_handle, symbol_name,
1232 else if (ht_kind == GNU_HASH_TABLE_KIND)
1233 return lookup_symbol_from_gnu_hash_tab(env,
1234 elf_handle, symbol_name,
1267lookup_symbol_from_symtab(
const environment& env,
1269 const string& sym_name,
1270 size_t sym_tab_index,
1272 vector<elf_symbol_sptr>& syms_found)
1277 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1280 GElf_Shdr header_mem;
1281 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1284 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1285 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1288 elf_symbol::version ver;
1291 for (
size_t i = 0; i < symcount; ++i)
1294 sym = gelf_getsym(symtab, i, &sym_mem);
1295 name_str = elf_strptr(elf_handle,
1296 sym_tab_header->sh_link,
1299 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1307 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1308 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1317 sym_binding, sym_is_defined,
1318 sym_is_common, ver, sym_visibility);
1319 syms_found.push_back(symbol_found);
1358lookup_symbol_from_elf(
const environment& env,
1360 const string& symbol_name,
1362 vector<elf_symbol_sptr>& syms_found)
1364 size_t hash_table_index = 0, symbol_table_index = 0;
1365 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1370 symbol_table_index);
1372 if (ht_kind == NO_HASH_TABLE_KIND)
1377 return lookup_symbol_from_symtab(env,
1385 return lookup_symbol_from_elf_hash_tab(env,
1409lookup_public_function_symbol_from_elf(environment& env,
1411 const string& symbol_name,
1412 vector<elf_symbol_sptr>& func_syms)
1414 vector<elf_symbol_sptr> syms_found;
1417 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1420 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1421 i != syms_found.end();
1427 if ((type == elf_symbol::FUNC_TYPE
1428 || type == elf_symbol::GNU_IFUNC_TYPE
1429 || type == elf_symbol::COMMON_TYPE)
1430 && (binding == elf_symbol::GLOBAL_BINDING
1431 || binding == elf_symbol::WEAK_BINDING))
1433 func_syms.push_back(*i);
1454 int64_t const_value_;
1462 expr_result(
bool is_const)
1463 : is_const_(is_const),
1467 explicit expr_result(int64_t v)
1493 const_value(int64_t& value)
1497 value = const_value_;
1513 return const_value_;
1516 operator int64_t()
const
1517 {
return const_value();}
1520 operator=(
const int64_t v)
1528 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1531 operator>=(
const expr_result& o)
const
1532 {
return const_value_ >= o.const_value_;}
1535 operator<=(
const expr_result& o)
const
1536 {
return const_value_ <= o.const_value_;}
1539 operator>(
const expr_result& o)
const
1540 {
return const_value_ > o.const_value_;}
1543 operator<(
const expr_result& o)
const
1544 {
return const_value_ < o.const_value_;}
1549 expr_result r(*
this);
1550 r.const_value_ += v.const_value_;
1551 r.is_const_ = r.is_const_ && v.is_const_;
1556 operator+=(int64_t v)
1563 operator-(
const expr_result& v)
const
1565 expr_result r(*
this);
1566 r.const_value_ -= v.const_value_;
1567 r.is_const_ = r.is_const_ && v.is_const_;
1572 operator%(
const expr_result& v)
const
1574 expr_result r(*
this);
1575 r.const_value_ %= v.const_value_;
1576 r.is_const_ = r.is_const_ && v.is_const();
1581 operator*(
const expr_result& v)
const
1583 expr_result r(*
this);
1584 r.const_value_ *= v.const_value_;
1585 r.is_const_ = r.is_const_ && v.is_const();
1592 expr_result r(*
this);
1593 r.const_value_ |= v.const_value_;
1594 r.is_const_ = r.is_const_ && v.is_const_;
1599 operator^(
const expr_result& v)
const
1601 expr_result r(*
this);
1602 r.const_value_ ^= v.const_value_;
1603 r.is_const_ = r.is_const_ && v.is_const_;
1608 operator>>(
const expr_result& v)
const
1610 expr_result r(*
this);
1611 r.const_value_ = r.const_value_ >> v.const_value_;
1612 r.is_const_ = r.is_const_ && v.is_const_;
1619 expr_result r(*
this);
1620 r.const_value_ = r.const_value_ << v.const_value_;
1621 r.is_const_ = r.is_const_ && v.is_const_;
1628 expr_result r(*
this);
1629 r.const_value_ = ~r.const_value_;
1636 expr_result r(*
this);
1637 r.const_value_ = -r.const_value_;
1644 expr_result r = *
this;
1645 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1652 expr_result r(*
this);
1653 r.const_value_ &= o.const_value_;
1654 r.is_const_ = r.is_const_ && o.is_const_;
1659 operator/(
const expr_result& o)
1661 expr_result r(*
this);
1662 r.is_const_ = r.is_const_ && o.is_const_;
1663 return r.const_value() / o.const_value();
1669class expr_result_stack_type
1671 vector<expr_result> elems_;
1675 expr_result_stack_type()
1676 {elems_.reserve(4);}
1679 operator[](
unsigned i)
1681 unsigned s = elems_.size();
1683 return elems_[s - 1 -i];
1687 operator[](
unsigned i)
const
1688 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1692 {
return elems_.size();}
1694 vector<expr_result>::reverse_iterator
1696 {
return elems_.rbegin();}
1698 const vector<expr_result>::reverse_iterator
1700 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1702 vector<expr_result>::reverse_iterator
1704 {
return elems_.rend();}
1706 const vector<expr_result>::reverse_iterator
1708 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1712 {
return elems_.back();}
1716 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1719 push_front(expr_result e)
1720 {elems_.push_back(e);}
1725 expr_result r = front();
1731 erase(vector<expr_result>::reverse_iterator i)
1732 {elems_.erase(--i.base());}
1740struct dwarf_expr_eval_context
1743 expr_result_stack_type stack;
1748 dwarf_expr_eval_context()
1752 stack.push_front(expr_result(
true));
1759 stack.push_front(expr_result(
true));
1760 accum = expr_result(
false);
1761 set_tls_addr =
false;
1770 set_tls_address(
bool f)
1779 set_tls_address()
const
1780 {
return set_tls_addr;}
1785 expr_result r = stack.front();
1791 push(
const expr_result& v)
1792 {stack.push_front(v);}
1801typedef shared_ptr<reader> reader_sptr;
1808class reader :
public elf_based_reader
1815 template <
typename ContainerType>
1816 class die_source_dependant_container_set
1818 ContainerType primary_debug_info_container_;
1819 ContainerType alt_debug_info_container_;
1820 ContainerType type_unit_container_;
1834 ContainerType *result = 0;
1837 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1838 result = &primary_debug_info_container_;
1840 case ALT_DEBUG_INFO_DIE_SOURCE:
1841 result = &alt_debug_info_container_;
1843 case TYPE_UNIT_DIE_SOURCE:
1844 result = &type_unit_container_;
1846 case NO_DEBUG_INFO_DIE_SOURCE:
1847 case NUMBER_OF_DIE_SOURCES:
1860 const ContainerType&
1863 return const_cast<die_source_dependant_container_set*
>(
this)->
1864 get_container(source);
1878 get_container(
const reader& rdr,
const Dwarf_Die *die)
1880 const die_source source = rdr.get_die_source(die);
1881 return get_container(source);
1894 const ContainerType&
1895 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1897 return const_cast<die_source_dependant_container_set*
>(
this)->
1898 get_container(rdr, die);
1905 primary_debug_info_container_.clear();
1906 alt_debug_info_container_.clear();
1907 type_unit_container_.clear();
1911 unsigned short dwarf_version_;
1912 Dwarf_Die* cur_tu_die_;
1913 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1917 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1918 decl_die_repr_die_offsets_maps_;
1922 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1923 type_die_repr_die_offsets_maps_;
1924 mutable die_source_dependant_container_set<die_istring_map_type>
1925 die_qualified_name_maps_;
1926 mutable die_source_dependant_container_set<die_istring_map_type>
1927 die_pretty_repr_maps_;
1928 mutable die_source_dependant_container_set<die_istring_map_type>
1929 die_pretty_type_repr_maps_;
1932 mutable die_source_dependant_container_set<die_artefact_map_type>
1933 decl_die_artefact_maps_;
1936 mutable die_source_dependant_container_set<die_artefact_map_type>
1937 type_die_artefact_maps_;
1940 mutable die_source_dependant_container_set<offset_offset_map_type>
1941 canonical_type_die_offsets_;
1944 mutable die_source_dependant_container_set<offset_offset_map_type>
1945 canonical_decl_die_offsets_;
1951 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1953 dwarf_offset_pair_hash> die_comparison_results_;
1963 vector<type_base_sptr> types_to_canonicalize_;
1982 list<var_decl_sptr> var_decls_to_add_;
1983#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1984 bool debug_die_canonicalization_is_on_;
1985 bool use_canonical_die_comparison_;
1987 mutable size_t compare_count_;
1988 mutable size_t canonical_propagated_count_;
1989 mutable size_t cancelled_propagation_count_;
1990 mutable optional<bool> leverage_dwarf_factorization_;
2025 reader(
const string& elf_path,
2026 const vector<char**>& debug_info_root_paths,
2027 environment& environment,
2028 bool load_all_types,
2029 bool linux_kernel_mode)
2031 debug_info_root_paths,
2034 initialize(load_all_types, linux_kernel_mode);
2052 initialize(
bool load_all_types,
bool linux_kernel_mode)
2056 decl_die_repr_die_offsets_maps_.clear();
2057 type_die_repr_die_offsets_maps_.clear();
2058 die_qualified_name_maps_.clear();
2059 die_pretty_repr_maps_.clear();
2060 die_pretty_type_repr_maps_.clear();
2061 decl_die_artefact_maps_.clear();
2062 type_die_artefact_maps_.clear();
2063 canonical_type_die_offsets_.clear();
2064 canonical_decl_die_offsets_.clear();
2065 die_wip_classes_map_.clear();
2066 alternate_die_wip_classes_map_.clear();
2067 type_unit_die_wip_classes_map_.clear();
2068 die_wip_function_types_map_.clear();
2069 alternate_die_wip_function_types_map_.clear();
2070 type_unit_die_wip_function_types_map_.clear();
2071 die_function_with_no_symbol_map_.clear();
2072 types_to_canonicalize_.clear();
2073 decl_only_classes_map_.clear();
2074 die_tu_map_.clear();
2078 primary_die_parent_map_.clear();
2079 tu_die_imported_unit_points_map_.clear();
2080 alt_tu_die_imported_unit_points_map_.clear();
2081 type_units_tu_die_imported_unit_points_map_.clear();
2082 alternate_die_parent_map_.clear();
2083 type_section_die_parent_map_.clear();
2084 var_decls_to_add_.clear();
2085 clear_per_translation_unit_data();
2086 options().load_in_linux_kernel_mode = linux_kernel_mode;
2087 options().load_all_types = load_all_types;
2088#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2089 debug_die_canonicalization_is_on_ =
2090 env().debug_die_canonicalization_is_on();
2091 use_canonical_die_comparison_ =
true;
2094 canonical_propagated_count_ = 0;
2095 cancelled_propagation_count_ = 0;
2096 load_in_linux_kernel_mode(linux_kernel_mode);
2118 const vector<char**>& debug_info_root_paths,
2119 bool load_all_types,
2120 bool linux_kernel_mode)
2123 initialize(load_all_types, linux_kernel_mode);
2143 static dwarf::reader_sptr
2144 create(
const std::string& elf_path,
2145 const vector<char**>& debug_info_root_paths,
2146 environment& environment,
2147 bool load_all_types,
2148 bool linux_kernel_mode)
2150 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2151 environment, load_all_types,
2152 linux_kernel_mode));
2169 read_corpus(status& status)
2176 if (!(status & STATUS_OK))
2180 return corpus_sptr();
2196 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2197 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2199 return corpus_sptr();
2203 corpus_sptr corp = read_debug_info_into_corpus();
2205 status |= STATUS_OK;
2218 read_debug_info_into_corpus()
2220 clear_per_corpus_data();
2225 origin |= corpus::DWARF_ORIGIN;
2226 corpus()->set_origin(origin);
2228 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2229 && !env().user_set_analyze_exported_interfaces_only())
2236 env().analyze_exported_interfaces_only(
true);
2242 corpus()->set_symtab(symtab());
2247 || !
corpus()->get_symtab()
2248 || !
corpus()->get_symtab()->has_symbols())
2251 uint8_t address_size = 0;
2252 size_t header_size = 0;
2254#ifdef WITH_DEBUG_SELF_COMPARISON
2255 if (env().self_comparison_debug_is_on())
2256 env().set_self_comparison_debug_input(
corpus());
2259 env().priv_->do_log(do_log());
2264 tools_utils::timer t;
2267 cerr <<
"building die -> parent maps ...";
2271 build_die_parent_maps();
2276 cerr <<
" DONE@" <<
corpus()->get_path()
2283 env().canonicalization_is_done(
false);
2286 tools_utils::timer t;
2289 cerr <<
"building the libabigail internal representation ...\n";
2293 Dwarf_Half dwarf_vers = 0;
2294 for (Dwarf_Off offset = 0, next_offset = 0;
2296 offset, &next_offset, &header_size,
2297 &dwarf_vers, NULL, &address_size, NULL,
2299 offset = next_offset)
2301 Dwarf_Off die_offset = offset + header_size;
2305 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2308 dwarf_version(dwarf_vers);
2315 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2321 cerr <<
"building the libabigail internal representation "
2322 <<
"DONE for corpus << corpus()->get_path()"
2327 cerr <<
"Number of aggregate types compared: "
2328 << compare_count_ <<
"\n"
2329 <<
"Number of canonical types propagated: "
2330 << canonical_propagated_count_ <<
"\n"
2331 <<
"Number of cancelled propagated canonical types:"
2332 << cancelled_propagation_count_ <<
"\n";
2337 tools_utils::timer t;
2340 cerr <<
"resolving declaration only classes ...";
2343 resolve_declaration_only_classes();
2347 cerr <<
" DONE@" <<
corpus()->get_path()
2355 tools_utils::timer t;
2358 cerr <<
"resolving declaration only enums ...";
2361 resolve_declaration_only_enums();
2365 cerr <<
" DONE@" <<
corpus()->get_path()
2373 tools_utils::timer t;
2376 cerr <<
"fixing up functions with linkage name but "
2377 <<
"no advertised underlying symbols ....";
2380 fixup_functions_with_no_symbols();
2384 cerr <<
" DONE@" <<
corpus()->get_path()
2391 merge_member_functions_in_classes_of_same_names();
2405 tools_utils::timer t;
2408 cerr <<
"perform late type canonicalizing ...\n";
2412 perform_late_type_canonicalizing();
2416 cerr <<
"late type canonicalizing DONE for "
2424 env().canonicalization_is_done(
true);
2427 tools_utils::timer t;
2430 cerr <<
"sort functions and variables ...";
2433 corpus()->sort_functions();
2434 corpus()->sort_variables();
2438 cerr <<
" DONE@" <<
corpus()->get_path()
2452 clear_per_translation_unit_data()
2454 while (!scope_stack().empty())
2455 scope_stack().pop();
2456 var_decls_to_re_add_to_tree().clear();
2457 per_tu_repr_to_fn_type_maps().clear();
2463 clear_per_corpus_data()
2465 die_qualified_name_maps_.clear();
2466 die_pretty_repr_maps_.clear();
2467 die_pretty_type_repr_maps_.clear();
2468 clear_types_to_canonicalize();
2483 {
return const_cast<reader*
>(
this)->env();}
2491 drop_undefined_syms()
const
2492 {
return options().drop_undefined_syms;}
2499 drop_undefined_syms(
bool f)
2500 {
options().drop_undefined_syms = f;}
2504 dwarf_version()
const
2505 {
return dwarf_version_;}
2508 dwarf_version(
unsigned short v)
2509 {dwarf_version_ = v;}
2521 dwarf_elf_handle()
const
2532 dwarf_is_splitted()
const
2533 {
return dwarf_elf_handle() != elf_handle();}
2542 dwarf_per_die_source(
die_source source)
const
2544 const Dwarf *result = 0;
2547 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2548 case TYPE_UNIT_DIE_SOURCE:
2551 case ALT_DEBUG_INFO_DIE_SOURCE:
2554 case NO_DEBUG_INFO_DIE_SOURCE:
2555 case NUMBER_OF_DIE_SOURCES:
2570 {
return cur_tu_die_;}
2573 cur_tu_die(Dwarf_Die* cur_tu_die)
2574 {cur_tu_die_ = cur_tu_die;}
2576 dwarf_expr_eval_context&
2577 dwarf_expr_eval_ctxt()
const
2578 {
return dwarf_expr_eval_context_;}
2585 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2586 decl_die_repr_die_offsets_maps()
const
2587 {
return decl_die_repr_die_offsets_maps_;}
2594 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2595 decl_die_repr_die_offsets_maps()
2596 {
return decl_die_repr_die_offsets_maps_;}
2603 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2604 type_die_repr_die_offsets_maps()
const
2605 {
return type_die_repr_die_offsets_maps_;}
2612 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2613 type_die_repr_die_offsets_maps()
2614 {
return type_die_repr_die_offsets_maps_;}
2627 compute_canonical_die_offset(
const Dwarf_Die *die,
2628 Dwarf_Off &canonical_die_offset,
2629 bool die_as_type)
const
2633 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2634 get_container(*
this, die)
2635 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2636 get_container(*
this, die);
2638 Dwarf_Die canonical_die;
2639 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2641 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2659 compute_canonical_die(
const Dwarf_Die *die,
2661 Dwarf_Die &canonical_die,
2662 bool die_as_type)
const
2664 const die_source source = get_die_source(die);
2666 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2668 compute_canonical_die(die_offset, source,
2670 canonical_die, die_as_type);
2690 compute_canonical_die(Dwarf_Off die_offset,
2693 Dwarf_Die &canonical_die,
2694 bool die_as_type)
const
2700 ? (
const_cast<reader*
>(
this)->
2701 type_die_repr_die_offsets_maps().get_container(source))
2702 : (
const_cast<reader*
>(
this)->
2703 decl_die_repr_die_offsets_maps().get_container(source));
2706 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2715 interned_string name =
2717 ? get_die_pretty_type_representation(&die, 0)
2718 : get_die_pretty_representation(&die, 0);
2720 Dwarf_Off canonical_die_offset = 0;
2721 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2725 offsets.push_back(die_offset);
2726 map[name] = offsets;
2727 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2728 get_die_from_offset(source, die_offset, &canonical_die);
2732 Dwarf_Off cur_die_offset;
2733 Dwarf_Die potential_canonical_die;
2734 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2735 o != i->second.end();
2738 cur_die_offset = *o;
2739 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2740 if (compare_dies(*
this, &die, &potential_canonical_die,
2743 canonical_die_offset = cur_die_offset;
2744 set_canonical_die_offset(canonical_dies, die_offset,
2745 canonical_die_offset);
2746 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2751 canonical_die_offset = die_offset;
2752 i->second.push_back(die_offset);
2753 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2754 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2773 get_canonical_die(
const Dwarf_Die *die,
2774 Dwarf_Die &canonical_die,
2778 const die_source source = get_die_source(die);
2782 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2783 get_container(source)
2784 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2785 get_container(source);
2787 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2788 if (Dwarf_Off canonical_die_offset =
2789 get_canonical_die_offset(canonical_dies, die_offset))
2791 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2799 ? (
const_cast<reader*
>(
this)->
2800 type_die_repr_die_offsets_maps().get_container(*
this, die))
2801 : (
const_cast<reader*
>(
this)->
2802 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2810 interned_string name =
2812 ? get_die_pretty_type_representation(die, where)
2813 : get_die_pretty_representation(die, where);
2815 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2819 Dwarf_Off cur_die_offset;
2820 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2821 o != i->second.end();
2824 cur_die_offset = *o;
2825 get_die_from_offset(source, cur_die_offset, &canonical_die);
2827 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2828 die, &canonical_die,
2831 set_canonical_die_offset(canonical_dies,
2865 get_or_compute_canonical_die(
const Dwarf_Die* die,
2866 Dwarf_Die& canonical_die,
2868 bool die_as_type)
const
2870 const die_source source = get_die_source(die);
2874 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2875 get_container(source)
2876 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2877 get_container(source);
2879 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2881 if (Dwarf_Off canonical_die_offset =
2882 get_canonical_die_offset(canonical_dies,
2883 initial_die_offset))
2885 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2889 if (!is_type_die_to_be_canonicalized(die))
2896 ? (
const_cast<reader*
>(
this)->
2897 type_die_repr_die_offsets_maps().get_container(*
this, die))
2898 : (
const_cast<reader*
>(
this)->
2899 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2907 interned_string name =
2909 ? get_die_pretty_type_representation(die, where)
2910 : get_die_pretty_representation(die, where);
2912 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2916 offsets.push_back(initial_die_offset);
2917 map[name] = offsets;
2918 get_die_from_offset(source, initial_die_offset, &canonical_die);
2919 set_canonical_die_offset(canonical_dies,
2921 initial_die_offset);
2928 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2931 Dwarf_Off die_offset = i->second[n];
2932 get_die_from_offset(source, die_offset, &canonical_die);
2934 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2935 die, &canonical_die,
2938 set_canonical_die_offset(canonical_dies,
2948 get_die_from_offset(source, initial_die_offset, &canonical_die);
2949 i->second.push_back(initial_die_offset);
2950 set_canonical_die_offset(canonical_dies,
2952 initial_die_offset);
2969 get_die_source(
const Dwarf_Die *die)
const
2971 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2992 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2996 uint8_t address_size = 0, offset_size = 0;
2997 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2998 &cu_die, &address_size,
3002 Dwarf_Half version = 0;
3003 Dwarf_Off abbrev_offset = 0;
3004 uint64_t type_signature = 0;
3005 Dwarf_Off type_offset = 0;
3006 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
3007 &version, &abbrev_offset,
3008 &address_size, &offset_size,
3009 &type_signature, &type_offset))
3012 int tag = dwarf_tag(&cu_kind);
3014 if (tag == DW_TAG_compile_unit
3015 || tag == DW_TAG_partial_unit)
3017 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
3019 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
3021 source = ALT_DEBUG_INFO_DIE_SOURCE;
3025 else if (tag == DW_TAG_type_unit)
3026 source = TYPE_UNIT_DIE_SOURCE;
3042 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
3044 if (source == TYPE_UNIT_DIE_SOURCE)
3045 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3048 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3075 associate_die_to_decl(Dwarf_Die* die,
3076 decl_base_sptr decl,
3077 size_t where_offset,
3078 bool do_associate_by_repr =
false)
3080 const die_source source = get_die_source(die);
3083 decl_die_artefact_maps().get_container(source);
3086 if (do_associate_by_repr)
3088 Dwarf_Die equiv_die;
3089 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
3092 die_offset = dwarf_dieoffset(&equiv_die);
3095 die_offset = dwarf_dieoffset(die);
3097 m[die_offset] = decl;
3119 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3121 decl_base_sptr result =
3122 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3141 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3145 die_qualified_name_maps_.get_container(*
this, die);
3147 size_t die_offset = dwarf_dieoffset(die);
3148 die_istring_map_type::const_iterator i = map.find(die_offset);
3152 reader& rdr = *
const_cast<reader*
>(
this);
3153 string qualified_name = die_qualified_name(rdr, die, where_offset);
3154 interned_string istr = env().intern(qualified_name);
3155 map[die_offset] = istr;
3175 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3177 return const_cast<reader*
>(
this)->
3178 get_die_qualified_name(die, where_offset);
3199 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3204 if (die == cur_tu_die())
3205 return env().intern(
"");
3208 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3211 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3212 die_istring_map_type::const_iterator i =
3213 map.find(die_offset);
3217 reader& rdr = *
const_cast<reader*
>(
this);
3218 string qualified_name;
3219 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3220 if ((tag == DW_TAG_structure_type
3221 || tag == DW_TAG_class_type
3222 || tag == DW_TAG_union_type)
3223 && die_is_anonymous(die))
3225 location l = die_location(*
this, die);
3226 qualified_name = l ? l.expand() :
"noloc";
3227 qualified_name =
"unnamed-at-" + qualified_name;
3231 die_qualified_type_name(rdr, die, where_offset);
3233 interned_string istr = env().intern(qualified_name);
3234 map[die_offset] = istr;
3258 get_die_pretty_type_representation(
const Dwarf_Die *die,
3259 size_t where_offset)
const
3263 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3266 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3267 die_istring_map_type::const_iterator i = map.find(die_offset);
3271 reader& rdr = *
const_cast<reader*
>(
this);
3272 string pretty_representation =
3273 die_pretty_print_type(rdr, die, where_offset);
3274 interned_string istr = env().intern(pretty_representation);
3275 map[die_offset] = istr;
3295 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3300 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3303 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3304 die_istring_map_type::const_iterator i = map.find(die_offset);
3308 reader& rdr = *
const_cast<reader*
>(
this);
3309 string pretty_representation =
3310 die_pretty_print(rdr, die, where_offset);
3311 interned_string istr = env().intern(pretty_representation);
3312 map[die_offset] = istr;
3336 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3339 lookup_artifact_from_die(die,
true);
3341 return fn->get_type();
3365 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3367 Dwarf_Die equiv_die;
3368 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3373 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3374 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3376 size_t die_offset = dwarf_dieoffset(&equiv_die);
3377 die_artefact_map_type::const_iterator i = m.find(die_offset);
3404 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3406 bool die_as_type =
false)
const
3410 ? type_die_artefact_maps().get_container(source)
3411 : decl_die_artefact_maps().get_container(source);
3413 die_artefact_map_type::const_iterator i = m.find(die_offset);
3456 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3471 if (!get_die_language(die, lang))
3482 die_source_dependant_container_set<die_artefact_map_type>&
3483 decl_die_artefact_maps()
3484 {
return decl_die_artefact_maps_;}
3491 const die_source_dependant_container_set<die_artefact_map_type>&
3492 decl_die_artefact_maps()
const
3493 {
return decl_die_artefact_maps_;}
3500 die_source_dependant_container_set<die_artefact_map_type>&
3501 type_die_artefact_maps()
3502 {
return type_die_artefact_maps_;}
3509 const die_source_dependant_container_set<die_artefact_map_type>&
3510 type_die_artefact_maps()
const
3511 {
return type_die_artefact_maps_;}
3519 per_tu_repr_to_fn_type_maps()
3520 {
return per_tu_repr_to_fn_type_maps_;}
3528 per_tu_repr_to_fn_type_maps()
const
3529 {
return per_tu_repr_to_fn_type_maps_;}
3539 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3542 if (!die_is_function_type(die))
3545 interned_string repr =
3546 get_die_pretty_type_representation(die, 0);
3549 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3560 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3562 if (!die_is_function_type(die))
3565 interned_string repr = die_name(die).empty() ?
3566 get_die_pretty_type_representation(die, 0)
3567 : get_die_pretty_representation(die, 0);
3570 istring_fn_type_map_type::const_iterator i =
3571 per_tu_repr_to_fn_type_maps().find(repr);
3573 if (i == per_tu_repr_to_fn_type_maps().end())
3590 Dwarf_Off die_offset,
3591 Dwarf_Off canonical_die_offset)
const
3593 canonical_dies[die_offset] = canonical_die_offset;}
3609 set_canonical_die_offset(Dwarf_Off die_offset,
3611 Dwarf_Off canonical_die_offset,
3612 bool die_as_type)
const
3616 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3617 get_container(source)
3618 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3619 get_container(source);
3621 set_canonical_die_offset(canonical_dies,
3623 canonical_die_offset);
3637 set_canonical_die_offset(
const Dwarf_Die *die,
3638 Dwarf_Off canonical_die_offset,
3639 bool die_as_type)
const
3641 const die_source source = get_die_source(die);
3643 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3645 set_canonical_die_offset(die_offset, source,
3646 canonical_die_offset,
3660 Dwarf_Off die_offset)
const
3662 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3663 if (it == canonical_dies.end())
3680 get_canonical_die_offset(Dwarf_Off die_offset,
3682 bool die_as_type)
const
3686 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3687 get_container(source)
3688 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3689 get_container(source);
3691 return get_canonical_die_offset(canonical_dies, die_offset);
3706 erase_canonical_die_offset(Dwarf_Off die_offset,
3708 bool die_as_type)
const
3712 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3713 get_container(source)
3714 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3715 get_container(source);
3717 return canonical_dies.erase(die_offset);
3730 associate_die_to_type(
const Dwarf_Die *die,
3731 type_base_sptr type,
3737 Dwarf_Die equiv_die;
3738 if (!get_or_compute_canonical_die(die, equiv_die, where,
3743 type_die_artefact_maps().get_container(*
this, &equiv_die);
3745 size_t die_offset = dwarf_dieoffset(&equiv_die);
3746 m[die_offset] = type;
3760 lookup_type_from_die(
const Dwarf_Die* die)
const
3763 lookup_artifact_from_die(die,
true);
3765 return fn->get_type();
3783 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3785 type_base_sptr result;
3787 type_die_artefact_maps().get_container(source);
3788 die_artefact_map_type::const_iterator i = m.find(die_offset);
3792 return fn->get_type();
3800 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3810 die_wip_function_types_map(source);
3811 die_function_type_map_type::const_iterator i = m.find(die_offset);
3830 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3845 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3847 case ALT_DEBUG_INFO_DIE_SOURCE:
3848 return alternate_die_wip_classes_map_;
3849 case TYPE_UNIT_DIE_SOURCE:
3850 return type_unit_die_wip_classes_map_;
3851 case NO_DEBUG_INFO_DIE_SOURCE:
3852 case NUMBER_OF_DIE_SOURCES:
3855 return die_wip_classes_map_;
3866 die_wip_function_types_map(
die_source source)
const
3867 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3877 die_wip_function_types_map(
die_source source)
3881 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3883 case ALT_DEBUG_INFO_DIE_SOURCE:
3884 return alternate_die_wip_function_types_map_;
3885 case TYPE_UNIT_DIE_SOURCE:
3886 return type_unit_die_wip_function_types_map_;
3887 case NO_DEBUG_INFO_DIE_SOURCE:
3888 case NUMBER_OF_DIE_SOURCES:
3891 return die_wip_function_types_map_;
3902 die_function_decl_with_no_symbol_map()
3903 {
return die_function_with_no_symbol_map_;}
3916 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3918 die_class_or_union_map_type::const_iterator i =
3919 die_wip_classes_map(source).find(offset);
3920 return (i != die_wip_classes_map(source).end());
3934 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3936 die_function_type_map_type::const_iterator i =
3937 die_wip_function_types_map(source).find(offset);
3938 return (i != die_wip_function_types_map(source).end());
3957 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3963 || dwarf_tag(die) != DW_TAG_member
3964 || !die_name(die).empty())
3970 if (die_is_anonymous_data_member(die))
3976 int64_t offset_in_bits = 0;
3977 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3981 loc = die_location(*
this, die);
3986 std::ostringstream o;
3987 o <<
"unnamed-dm-@-";
3989 o <<
"offset-" << offset_in_bits <<
"bits";
3991 o <<
"loc-" << loc.expand();
4004 declaration_only_classes()
const
4005 {
return decl_only_classes_map_;}
4015 declaration_only_classes()
4016 {
return decl_only_classes_map_;}
4024 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
4026 if (cou->get_is_declaration_only()
4027 && cou->get_definition_of_declaration() == 0
4032 && !cou->get_qualified_name().empty())
4034 string qn = cou->get_qualified_name();
4035 string_classes_or_unions_map::iterator record =
4036 declaration_only_classes().find(qn);
4037 if (record == declaration_only_classes().end())
4038 declaration_only_classes()[qn].push_back(cou);
4040 record->second.push_back(cou);
4052 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4054 if (cou->get_is_declaration_only())
4055 return ((declaration_only_classes().find(cou->get_qualified_name())
4056 != declaration_only_classes().end())
4057 || (declaration_only_classes().find(cou->get_name())
4058 != declaration_only_classes().end()));
4078 const environment& e = l->get_environment();
4081 e.priv_->allow_type_comparison_results_caching(
true);
4082 bool s0 = e.decl_only_class_equals_definition();
4083 e.decl_only_class_equals_definition(
true);
4084 bool equal = l == r;
4085 e.decl_only_class_equals_definition(s0);
4086 e.priv_->clear_type_comparison_results_cache();
4087 e.priv_->allow_type_comparison_results_caching(
false);
4094 resolve_declaration_only_classes()
4096 vector<string> resolved_classes;
4098 for (string_classes_or_unions_map::iterator i =
4099 declaration_only_classes().begin();
4100 i != declaration_only_classes().end();
4103 bool to_resolve =
false;
4104 for (classes_or_unions_type::iterator j = i->second.begin();
4105 j != i->second.end();
4107 if ((*j)->get_is_declaration_only()
4108 && ((*j)->get_definition_of_declaration() == 0))
4113 resolved_classes.push_back(i->first);
4158 map<string, class_or_union_sptr> per_tu_class_map;
4159 for (type_base_wptrs_type::const_iterator c = classes->begin();
4160 c != classes->end();
4167 if (klass->get_is_declaration_only())
4170 string tu_path = klass->get_translation_unit()->get_absolute_path();
4171 if (tu_path.empty())
4177 per_tu_class_map[tu_path] = klass;
4180 if (!per_tu_class_map.empty())
4186 for (classes_or_unions_type::iterator j = i->second.begin();
4187 j != i->second.end();
4190 if ((*j)->get_is_declaration_only()
4191 && ((*j)->get_definition_of_declaration() == 0))
4194 (*j)->get_translation_unit()->get_absolute_path();
4195 map<string, class_or_union_sptr>::const_iterator e =
4196 per_tu_class_map.find(tu_path);
4197 if (e != per_tu_class_map.end())
4198 (*j)->set_definition_of_declaration(e->second);
4199 else if (per_tu_class_map.size() == 1)
4200 (*j)->set_definition_of_declaration
4201 (per_tu_class_map.begin()->second);
4211 class_or_union_sptr>::const_iterator it;
4212 class_or_union_sptr first_class =
4213 per_tu_class_map.begin()->second;
4214 bool all_class_definitions_are_equal =
true;
4215 for (it = per_tu_class_map.begin();
4216 it != per_tu_class_map.end();
4219 if (it == per_tu_class_map.begin())
4223 if (!compare_before_canonicalisation(it->second,
4226 all_class_definitions_are_equal =
false;
4231 if (all_class_definitions_are_equal)
4232 (*j)->set_definition_of_declaration(first_class);
4236 resolved_classes.push_back(i->first);
4240 size_t num_decl_only_classes = declaration_only_classes().size(),
4241 num_resolved = resolved_classes.size();
4243 cerr <<
"resolved " << num_resolved
4244 <<
" class declarations out of "
4245 << num_decl_only_classes
4248 for (vector<string>::const_iterator i = resolved_classes.begin();
4249 i != resolved_classes.end();
4251 declaration_only_classes().erase(*i);
4253 if (show_stats() && !declaration_only_classes().empty())
4255 cerr <<
"Here are the "
4256 << num_decl_only_classes - num_resolved
4257 <<
" unresolved class declarations:\n";
4258 for (string_classes_or_unions_map::iterator i =
4259 declaration_only_classes().begin();
4260 i != declaration_only_classes().end();
4262 cerr <<
" " << i->first <<
"\n";
4274 declaration_only_enums()
const
4275 {
return decl_only_enums_map_;}
4285 declaration_only_enums()
4286 {
return decl_only_enums_map_;}
4296 if (enom->get_is_declaration_only()
4297 && enom->get_definition_of_declaration() == 0
4302 && !enom->get_qualified_name().empty())
4304 string qn = enom->get_qualified_name();
4305 string_enums_map::iterator record =
4306 declaration_only_enums().find(qn);
4307 if (record == declaration_only_enums().end())
4308 declaration_only_enums()[qn].push_back(enom);
4310 record->second.push_back(enom);
4324 if (enom->get_is_declaration_only())
4325 return (declaration_only_enums().find(enom->get_qualified_name())
4326 != declaration_only_enums().end());
4339 resolve_declaration_only_enums()
4341 vector<string> resolved_enums;
4343 for (string_enums_map::iterator i =
4344 declaration_only_enums().begin();
4345 i != declaration_only_enums().end();
4348 bool to_resolve =
false;
4349 for (enums_type::iterator j = i->second.begin();
4350 j != i->second.end();
4352 if ((*j)->get_is_declaration_only()
4353 && ((*j)->get_definition_of_declaration() == 0))
4358 resolved_enums.push_back(i->first);
4400 map<string, enum_type_decl_sptr> per_tu_enum_map;
4401 for (type_base_wptrs_type::const_iterator c = enums->begin();
4409 if (enom->get_is_declaration_only())
4412 string tu_path = enom->get_translation_unit()->get_absolute_path();
4413 if (tu_path.empty())
4419 per_tu_enum_map[tu_path] = enom;
4422 if (!per_tu_enum_map.empty())
4428 for (enums_type::iterator j = i->second.begin();
4429 j != i->second.end();
4432 if ((*j)->get_is_declaration_only()
4433 && ((*j)->get_definition_of_declaration() == 0))
4436 (*j)->get_translation_unit()->get_absolute_path();
4437 map<string, enum_type_decl_sptr>::const_iterator e =
4438 per_tu_enum_map.find(tu_path);
4439 if (e != per_tu_enum_map.end())
4440 (*j)->set_definition_of_declaration(e->second);
4441 else if (per_tu_enum_map.size() == 1)
4442 (*j)->set_definition_of_declaration
4443 (per_tu_enum_map.begin()->second);
4455 per_tu_enum_map.begin()->second;
4456 bool all_enum_definitions_are_equal =
true;
4457 for (it = per_tu_enum_map.begin();
4458 it != per_tu_enum_map.end();
4461 if (it == per_tu_enum_map.begin())
4465 if (!compare_before_canonicalisation(it->second,
4468 all_enum_definitions_are_equal =
false;
4473 if (all_enum_definitions_are_equal)
4474 (*j)->set_definition_of_declaration(first_enum);
4478 resolved_enums.push_back(i->first);
4482 size_t num_decl_only_enums = declaration_only_enums().size(),
4483 num_resolved = resolved_enums.size();
4485 cerr <<
"resolved " << num_resolved
4486 <<
" enum declarations out of "
4487 << num_decl_only_enums
4490 for (vector<string>::const_iterator i = resolved_enums.begin();
4491 i != resolved_enums.end();
4493 declaration_only_enums().erase(*i);
4495 if (show_stats() && !declaration_only_enums().empty())
4497 cerr <<
"Here are the "
4498 << num_decl_only_enums - num_resolved
4499 <<
" unresolved enum declarations:\n";
4500 for (string_enums_map::iterator i = declaration_only_enums().begin();
4501 i != declaration_only_enums().end();
4503 cerr <<
" " << i->first <<
"\n";
4519 corpus_sptr corp =
corpus();
4523 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4525 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4530 if (f->get_symbol())
4550 fixup_functions_with_no_symbols()
4552 corpus_sptr corp =
corpus();
4557 die_function_decl_with_no_symbol_map();
4560 cerr << fns_with_no_symbol.size()
4561 <<
" functions to fixup, potentially\n";
4563 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4564 i != fns_with_no_symbol.end();
4567 corp->lookup_function_symbol(i->second->get_linkage_name()))
4582 if (i->second->get_symbol()
4583 || symbol_already_belongs_to_a_function(sym))
4588 i->second->set_symbol(sym);
4591 cerr <<
"fixed up '"
4592 << i->second->get_pretty_representation()
4593 <<
"' with symbol '"
4594 << sym->get_id_string()
4598 fns_with_no_symbol.clear();
4611 for (
auto method : src_class->get_member_functions())
4612 if (!method->get_linkage_name().empty())
4613 if (!dest_class->find_member_function(method->get_linkage_name()))
4615 method_decl_sptr copied_method =
4618 schedule_type_for_late_canonicalization(copied_method->get_type());
4629 template <
typename iterator_type>
4631 contains_anonymous_class(
const iterator_type& begin,
4632 const iterator_type& end)
4634 for (
auto i = begin; i < end; ++i)
4636 type_base_sptr t(*i);
4638 if (c && c->get_is_anonymous())
4654 template <
typename iterator_type>
4656 merge_member_functions_of_classes(
const iterator_type& begin,
4657 const iterator_type& end)
4659 if (contains_anonymous_class(begin, end))
4662 for (
auto i = begin; i < end; ++i)
4664 type_base_sptr t(*i);
4666 if (!reference_class)
4669 string n1 = reference_class->get_pretty_representation(
true,
true);
4671 for (
auto j = begin; j < end; ++j)
4676 type_base_sptr type(*j);
4681 n2 = klass->get_pretty_representation(
true,
true);
4684 copy_missing_member_functions(reference_class, klass);
4685 copy_missing_member_functions(klass, reference_class);
4694 merge_member_functions_in_classes_of_same_names()
4696 corpus_sptr abi =
corpus();
4701 abi->get_types().class_types();
4703 for (
auto entry : class_types)
4705 auto& classes = entry.second;
4706 if (classes.size() > 1)
4708 bool a_class_has_member_fns =
false;
4709 for (
auto& c : classes)
4711 type_base_sptr t(c);
4713 if (!klass->get_member_functions().empty())
4715 a_class_has_member_fns =
true;
4719 if (a_class_has_member_fns)
4720 merge_member_functions_of_classes(classes.begin(),
4728 const vector<type_base_sptr>&
4729 types_to_canonicalize()
const
4730 {
return types_to_canonicalize_;}
4734 vector<type_base_sptr>&
4735 types_to_canonicalize()
4736 {
return types_to_canonicalize_;}
4740 clear_types_to_canonicalize()
4742 types_to_canonicalize_.clear();
4750 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4752 types_to_canonicalize_.push_back(t);
4762 canonicalize_types_scheduled()
4764 tools_utils::timer cn_timer;
4767 cerr <<
"DWARF Reader is going to canonicalize types";
4768 corpus_sptr c =
corpus();
4770 cerr <<
" of corpus " <<
corpus()->get_path() <<
"\n";
4774 if (!types_to_canonicalize().empty())
4776 types_to_canonicalize().end(),
4777 [](
const vector<type_base_sptr>::const_iterator& i)
4783 cerr <<
"finished canonicalizing types";
4784 corpus_sptr c =
corpus();
4786 cerr <<
" of corpus " <<
corpus()->get_path();
4787 cerr <<
": (" << cn_timer <<
")\n";
4804 add_late_canonicalized_types_stats(
size_t& canonicalized,
4805 size_t& missed)
const
4807 for (
auto t : types_to_canonicalize())
4809 if (t->get_canonical_type())
4819 perform_late_type_canonicalizing()
4821 canonicalize_types_scheduled();
4825 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4826 add_late_canonicalized_types_stats(num_canonicalized,
4828 total = num_canonicalized + num_missed;
4832 cerr <<
" # late canonicalized types: "
4833 << num_canonicalized;
4835 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4837 <<
" # missed canonicalization opportunities: "
4840 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4848 {
return die_tu_map_;}
4852 {
return die_tu_map_;}
4861 tu_die_imported_unit_points_map(
die_source source)
const
4862 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4871 tu_die_imported_unit_points_map(
die_source source)
4875 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4877 case ALT_DEBUG_INFO_DIE_SOURCE:
4878 return alt_tu_die_imported_unit_points_map_;
4879 case TYPE_UNIT_DIE_SOURCE:
4880 return type_units_tu_die_imported_unit_points_map_;
4881 case NO_DEBUG_INFO_DIE_SOURCE:
4882 case NUMBER_OF_DIE_SOURCES:
4886 return tu_die_imported_unit_points_map_;
4904 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4917 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4919 case ALT_DEBUG_INFO_DIE_SOURCE:
4920 return alternate_die_parent_map_;
4921 case TYPE_UNIT_DIE_SOURCE:
4922 return type_section_die_parent_map();
4923 case NO_DEBUG_INFO_DIE_SOURCE:
4924 case NUMBER_OF_DIE_SOURCES:
4927 return primary_die_parent_map_;
4931 type_section_die_parent_map()
const
4932 {
return type_section_die_parent_map_;}
4935 type_section_die_parent_map()
4936 {
return type_section_die_parent_map_;}
4942 cur_transl_unit()
const
4966 global_scope()
const
4967 {
return cur_transl_unit()->get_global_scope();}
4974 {
return nil_scope_;}
4978 {
return scope_stack_;}
4982 {
return scope_stack_;}
4987 if (scope_stack().empty())
4989 if (cur_transl_unit())
4992 return scope_stack().top();
4995 list<var_decl_sptr>&
4996 var_decls_to_re_add_to_tree()
4997 {
return var_decls_to_add_;}
5010 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
const
5012 if (!die || !die_is_decl(die))
5015 bool result =
false, address_found =
false, symbol_is_exported =
false;;
5016 Dwarf_Addr decl_symbol_address = 0;
5018 if (die_is_variable_decl(die))
5020 if ((address_found = get_variable_address(die, decl_symbol_address)))
5021 symbol_is_exported =
5024 else if (die_is_function_decl(die))
5026 if ((address_found = get_function_address(die, decl_symbol_address)))
5027 symbol_is_exported =
5032 result = symbol_is_exported;
5043 is_decl_die_with_undefined_symbol(
const Dwarf_Die *die)
const
5045 if (is_decl_die_with_exported_symbol(die))
5048 string name, linkage_name;
5049 die_name_and_linkage_name(die, name, linkage_name);
5050 if (linkage_name.empty())
5051 linkage_name = name;
5053 bool result =
false;
5054 if ((die_is_variable_decl(die)
5057 (die_is_function_decl(die)
5078 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
5084 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
5086 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
5088 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
5090 dwarf_elf_load_address));
5093 if (dwarf_is_splitted()
5094 && (dwarf_elf_load_address != elf_load_address))
5105 addr = addr - dwarf_elf_load_address + elf_load_address;
5131 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
5136 Elf* elf = elf_handle();
5138 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5140 if (elf_header->e_type == ET_REL)
5153 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5178 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
5180 Elf* elf = elf_handle();
5182 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5184 if (elf_header->e_type == ET_REL)
5197 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5216 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5217 Dwarf_Addr& address)
const
5220 Dwarf_Addr end_addr;
5221 ptrdiff_t offset = 0;
5225 Dwarf_Addr addr = 0, fn_addr = 0;
5226 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5228 fn_addr = maybe_adjust_fn_sym_address(addr);
5235 }
while (offset > 0);
5253 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5255 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5256 DW_AT_low_pc, address))
5262 if (!get_first_exported_fn_address_from_DW_AT_ranges
5263 (
const_cast<Dwarf_Die*
>(function_die),
5267 address = maybe_adjust_fn_sym_address(address);
5286 get_variable_address(
const Dwarf_Die* variable_die,
5287 Dwarf_Addr& address)
const
5289 bool is_tls_address =
false;
5290 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5291 address, is_tls_address))
5293 if (!is_tls_address)
5294 address = maybe_adjust_var_sym_address(address);
5301 corpus::exported_decls_builder*
5302 exported_decls_builder()
5303 {
return corpus()->get_exported_decls_builder().get();}
5311 load_all_types()
const
5312 {
return options().load_all_types;}
5320 load_all_types(
bool f)
5321 {
options().load_all_types = f;}
5324 load_in_linux_kernel_mode()
const
5325 {
return options().load_in_linux_kernel_mode;}
5328 load_in_linux_kernel_mode(
bool f)
5329 {
options().load_in_linux_kernel_mode = f;}
5341 load_undefined_interfaces()
const
5352 leverage_dwarf_factorization()
const
5354 if (!leverage_dwarf_factorization_.has_value())
5356 if (
options().leverage_dwarf_factorization
5357 && elf_helpers::find_section_by_name(elf_handle(),
5358 ".gnu_debugaltlink"))
5359 leverage_dwarf_factorization_ =
true;
5361 leverage_dwarf_factorization_ =
false;
5363 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5365 return *leverage_dwarf_factorization_;
5375 {
return options().show_stats;}
5424 build_die_parent_relations_under(Dwarf_Die* die,
5434 if (dwarf_child(die, &child) != 0)
5439 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5440 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5442 Dwarf_Die imported_unit;
5443 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5454 && die_has_children(&imported_unit))
5456 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5457 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5458 imported_units.push_back
5459 (imported_unit_point(dwarf_dieoffset(&child),
5461 imported_unit_die_source));
5464 build_die_parent_relations_under(&child, source, imported_units);
5466 while (dwarf_siblingof(&child, &child) == 0);
5498 case translation_unit::LANG_UNKNOWN:
5499#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5500 case translation_unit::LANG_Mips_Assembler:
5527 build_die_parent_maps()
5529 bool we_do_have_to_build_die_parent_map =
false;
5530 uint8_t address_size = 0;
5531 size_t header_size = 0;
5536 for (Dwarf_Off offset = 0, next_offset = 0;
5538 offset, &next_offset, &header_size,
5539 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5540 offset = next_offset)
5542 Dwarf_Off die_offset = offset + header_size;
5549 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5551 if (do_we_build_die_parent_maps(lang))
5552 we_do_have_to_build_die_parent_map =
true;
5555 if (!we_do_have_to_build_die_parent_map)
5560 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5561 for (Dwarf_Off offset = 0, next_offset = 0;
5563 offset, &next_offset, &header_size,
5564 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5565 offset = next_offset)
5567 Dwarf_Off die_offset = offset + header_size;
5575 tu_die_imported_unit_points_map(source)[die_offset] =
5577 build_die_parent_relations_under(&cu, source, imported_units);
5582 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5585 for (Dwarf_Off offset = 0, next_offset = 0;
5587 offset, &next_offset, &header_size,
5588 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5589 offset = next_offset)
5591 Dwarf_Off die_offset = offset + header_size;
5598 tu_die_imported_unit_points_map(source)[die_offset] =
5600 build_die_parent_relations_under(&cu, source, imported_units);
5605 source = TYPE_UNIT_DIE_SOURCE;
5608 uint64_t type_signature = 0;
5609 Dwarf_Off type_offset;
5610 for (Dwarf_Off offset = 0, next_offset = 0;
5612 offset, &next_offset, &header_size,
5613 NULL, NULL, &address_size, NULL,
5614 &type_signature, &type_offset) == 0);
5615 offset = next_offset)
5617 Dwarf_Off die_offset = offset + header_size;
5625 tu_die_imported_unit_points_map(source)[die_offset] =
5627 build_die_parent_relations_under(&cu, source, imported_units);
5642struct offset_pairs_stack_type
5659 offset_pairs_stack_type(
const reader& rdr)
5685 offset_pair_vector_type::iterator i;
5687 for (i = vect_.begin();i < vect_.end(); ++i)
5691 if (i != vect_.end())
5710 if (set_.find(p) == set_.end())
5737 bool result =
false;
5742 offset_pair_vector_type::const_iterator i;
5743 for (i = vect_.begin(); i != vect_.end(); ++i)
5747 if (i == vect_.end())
5752 for (++i; i != vect_.end(); ++i)
5754 pairs.push_back(*i);
5774 for (
auto type_pair : dependant_types)
5775 dependant_types_[type_pair].push_back(p);
5786 get_pairs_that_depend_on(p, dependant_types);
5789 auto it = redundant_types_.find(p);
5790 if (it == redundant_types_.end())
5792 auto entry = std::make_pair(p, dependant_types);
5793 redundant_types_.insert(entry);
5796 it->second.insert(it->second.end(),
5797 dependant_types.begin(),
5798 dependant_types.end());
5802 record_dependant_types(p, dependant_types);
5813 auto i = redundant_types_.find(p);
5814 if (i != redundant_types_.end())
5827 auto i = dependant_types_.find(p);
5828 if (i == dependant_types_.end())
5846 bool erase_cached_results =
false)
5850 auto redundant_type = redundant_types_.find(p);
5851 if (redundant_type != redundant_types_.end())
5853 for (
auto dependant_type : redundant_type->second)
5857 auto dependant_types_it = dependant_types_.find(dependant_type);
5858 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5862 auto i = dependant_types_it->second.begin();
5863 for (; i!= dependant_types_it->second.end();++i)
5866 if (i != dependant_types_it->second.end())
5867 dependant_types_it->second.erase(i);
5872 if (dependant_types_it->second.empty())
5874 if (erase_cached_results)
5875 rdr_.die_comparison_results_.erase(dependant_type);
5876 dependant_types_.erase(dependant_types_it);
5880 if (erase_cached_results)
5881 rdr_.die_comparison_results_.erase(p);
5882 redundant_types_.erase(p);
5894 {erase_redundant_type_pair_entry(p,
true);}
5907 get_dependant_types(p, dependant_types,
true);
5908 for (
auto dependant_type : dependant_types)
5912 if (rdr_.propagated_types_.find(dependant_type)
5913 != rdr_.propagated_types_.end())
5915 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5916 dependant_type.first.source_,
5918 rdr_.propagated_types_.erase(dependant_type);
5919 rdr_.cancelled_propagation_count_++;
5923 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5924 if (comp_result_it != rdr_.die_comparison_results_.end())
5925 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5929 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5930 if (comp_result_it != rdr_.die_comparison_results_.end())
5937 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5938 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5939 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5942 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5944 rdr_.erase_canonical_die_offset(p.first.offset_,
5947 rdr_.propagated_types_.erase(p);
5948 rdr_.cancelled_propagation_count_++;
5967 bool transitive_closure =
false)
5969 auto i = redundant_types_.find(p);
5970 if (i != redundant_types_.end())
5972 for (
auto dependant_type : i->second)
5973 if (result.find(dependant_type) == result.end())
5975 result.insert(dependant_type);
5976 if (transitive_closure)
5977 get_dependant_types(p, result,
true);
5986build_ir_node_from_die(reader& rdr,
5989 bool called_from_public_decl,
5990 size_t where_offset,
5991 bool is_declaration_only =
true,
5992 bool is_required_decl_spec =
false);
5995build_ir_node_from_die(reader& rdr,
5997 bool called_from_public_decl,
5998 size_t where_offset);
6000static decl_base_sptr
6001build_ir_node_for_void_type(reader& rdr);
6004build_ir_node_for_void_pointer_type(reader& rdr);
6007add_or_update_class_type(reader& rdr,
6012 bool called_from_public_decl,
6013 size_t where_offset,
6014 bool is_declaration_only);
6016static union_decl_sptr
6017add_or_update_union_type(reader& rdr,
6020 union_decl_sptr union_type,
6021 bool called_from_public_decl,
6022 size_t where_offset,
6023 bool is_declaration_only);
6025static decl_base_sptr
6026build_ir_node_for_void_type(reader& rdr);
6028static decl_base_sptr
6029build_ir_node_for_variadic_parameter_type(reader &rdr);
6032build_function_decl(reader& rdr,
6034 size_t where_offset,
6038function_is_suppressed(
const reader& rdr,
6039 const scope_decl* scope,
6040 Dwarf_Die *function_die,
6041 bool is_declaration_only);
6044build_or_get_fn_decl_if_not_suppressed(reader& rdr,
6047 size_t where_offset,
6048 bool is_declaration_only,
6052build_var_decl(reader& rdr,
6054 size_t where_offset,
6058build_or_get_var_decl_if_not_suppressed(reader& rdr,
6061 size_t where_offset,
6062 bool is_declaration_only,
6064 bool is_required_decl_spec =
false);
6066variable_is_suppressed(
const reader& rdr,
6067 const scope_decl* scope,
6068 Dwarf_Die *variable_die,
6069 bool is_declaration_only,
6070 bool is_required_decl_spec =
false);
6073finish_member_function_reading(Dwarf_Die* die,
6075 const class_or_union_sptr klass,
6084die_is_anonymous(
const Dwarf_Die* die)
6086 Dwarf_Attribute attr;
6087 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
6101die_is_anonymous_data_member(
const Dwarf_Die* die)
6104 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
6105 || !die_name(die).empty())
6109 if (!die_die_attribute(die, DW_AT_type, type_die))
6112 if (dwarf_tag(&type_die) != DW_TAG_structure_type
6113 && dwarf_tag(&type_die) != DW_TAG_union_type)
6130die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6135 Dwarf_Attribute attr;
6136 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6139 const char* str = dwarf_formstring(&attr);
6140 return str ? str :
"";
6154die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6159 Dwarf_Attribute attr;
6160 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6163 const char* str = dwarf_formstring(&attr);
6183die_unsigned_constant_attribute(
const Dwarf_Die* die,
6190 Dwarf_Attribute attr;
6191 Dwarf_Word result = 0;
6192 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6193 || dwarf_formudata(&attr, &result))
6213die_signed_constant_attribute(
const Dwarf_Die *die,
6220 Dwarf_Attribute attr;
6221 Dwarf_Sword result = 0;
6222 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6223 || dwarf_formsdata(&attr, &result))
6249die_constant_attribute(
const Dwarf_Die *die,
6252 array_type_def::subrange_type::bound_value &value)
6257 if (!die_unsigned_constant_attribute(die, attr_name, l))
6259 value.set_unsigned(l);
6264 if (!die_signed_constant_attribute(die, attr_name, l))
6266 value.set_signed(l);
6281form_is_DW_FORM_strx(
unsigned form)
6285#if defined HAVE_DW_FORM_strx1 \
6286 && defined HAVE_DW_FORM_strx2 \
6287 && defined HAVE_DW_FORM_strx3 \
6288 && defined HAVE_DW_FORM_strx4
6289 if (form == DW_FORM_strx1
6290 || form == DW_FORM_strx2
6291 || form == DW_FORM_strx3
6292 ||form == DW_FORM_strx4)
6309form_is_DW_FORM_line_strp(
unsigned form)
6313#if defined HAVE_DW_FORM_line_strp
6314 if (form == DW_FORM_line_strp)
6341die_flag_attribute(
const Dwarf_Die* die,
6344 bool recursively =
true)
6346 Dwarf_Attribute attr;
6348 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6349 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6353 if (dwarf_formflag(&attr, &f))
6367die_linkage_name(
const Dwarf_Die* die)
6372 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6373 if (linkage_name.empty())
6374 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6375 return linkage_name;
6389die_decl_file_attribute(
const Dwarf_Die* die)
6394 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6396 return str ? str :
"";
6417die_die_attribute(
const Dwarf_Die* die,
6422 Dwarf_Attribute attr;
6424 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6425 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6428 return dwarf_formref_die(&attr, &result);
6453die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6455 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6456 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6458 while (die_die_attribute(&origin_die,
6459 DW_AT_specification,
6461 || die_die_attribute(&origin_die,
6462 DW_AT_abstract_origin,
6500subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6502 Dwarf_Die& referenced_subrange)
6504 bool result =
false;
6506 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6509 Dwarf_Die referenced_die;
6510 if (die_die_attribute(die, attr_name, referenced_die))
6512 unsigned tag = dwarf_tag(&referenced_die);
6513 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6516 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6518 tag = dwarf_tag(&type_die);
6519 if (tag == DW_TAG_subrange_type)
6521 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6557subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6559 array_type_def::subrange_type::bound_value& v,
6562 bool result =
false;
6564 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6567 Dwarf_Die subrange_die;
6568 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6571 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6589die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6591 Dwarf_Attribute attr;
6592 if (!dwarf_attr_integrate(die, attr_name, &attr))
6594 return dwarf_formaddr(&attr, &result) == 0;
6605die_location(
const reader& rdr,
const Dwarf_Die* die)
6610 string file = die_decl_file_attribute(die);
6612 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6614 if (!file.empty() && line != 0)
6617 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6629die_name(
const Dwarf_Die* die)
6631 string name = die_string_attribute(die, DW_AT_name);
6647die_loc_and_name(
const reader& rdr,
6651 string& linkage_name)
6653 loc = die_location(rdr, die);
6654 name = die_name(die);
6655 linkage_name = die_linkage_name(die);
6666die_name_and_linkage_name(
const Dwarf_Die* die,
6668 string& linkage_name)
6670 name = die_name(die);
6671 linkage_name = die_linkage_name(die);
6684die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6689 uint64_t byte_size = 0, bit_size = 0;
6691 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6693 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6697 bit_size = byte_size * 8;
6720 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6727 case private_access:
6728 result = private_access;
6731 case protected_access:
6732 result = protected_access;
6736 result = public_access;
6755die_is_public_decl(
const Dwarf_Die* die)
6759 bool is_public =
false;
6765 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6766 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6767 die_flag_attribute(die, DW_AT_external, is_public);
6768 else if (tag == DW_TAG_namespace)
6770 string name = die_name(die);
6771 is_public = !name.empty();
6785die_is_effectively_public_decl(
const reader& rdr,
6786 const Dwarf_Die* die)
6788 if (die_is_public_decl(die))
6791 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6792 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6795 Dwarf_Die parent_die;
6796 size_t where_offset = 0;
6797 if (!get_parent_die(rdr, die, parent_die, where_offset))
6800 tag = dwarf_tag(&parent_die);
6801 if (tag == DW_TAG_compile_unit
6802 || tag == DW_TAG_partial_unit
6803 || tag == DW_TAG_type_unit)
6807 if (tag == DW_TAG_namespace)
6809 string name = die_name(&parent_die);
6828die_is_declaration_only(Dwarf_Die* die)
6830 bool is_declaration =
false;
6831 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6832 if (is_declaration && !die_has_size_attribute(die))
6843die_is_function_decl(
const Dwarf_Die *die)
6848 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6849 if (tag == DW_TAG_subprogram)
6860die_is_variable_decl(
const Dwarf_Die *die)
6865 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6866 if (tag == DW_TAG_variable)
6877die_has_size_attribute(
const Dwarf_Die *die)
6880 if (die_size_in_bits(die, s))
6891die_has_no_child(
const Dwarf_Die *die)
6897 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6910die_is_declaration_only(
const Dwarf_Die* die)
6911{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6919die_is_artificial(Dwarf_Die* die)
6922 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6929is_type_tag(
unsigned tag)
6931 bool result =
false;
6935 case DW_TAG_array_type:
6936 case DW_TAG_class_type:
6937 case DW_TAG_enumeration_type:
6938 case DW_TAG_pointer_type:
6939 case DW_TAG_reference_type:
6940 case DW_TAG_string_type:
6941 case DW_TAG_structure_type:
6942 case DW_TAG_subroutine_type:
6943 case DW_TAG_typedef:
6944 case DW_TAG_union_type:
6945 case DW_TAG_ptr_to_member_type:
6946 case DW_TAG_set_type:
6947 case DW_TAG_subrange_type:
6948 case DW_TAG_base_type:
6949 case DW_TAG_const_type:
6950 case DW_TAG_file_type:
6951 case DW_TAG_packed_type:
6952 case DW_TAG_thrown_type:
6953 case DW_TAG_volatile_type:
6954 case DW_TAG_restrict_type:
6955 case DW_TAG_interface_type:
6956 case DW_TAG_unspecified_type:
6957 case DW_TAG_shared_type:
6958 case DW_TAG_rvalue_reference_type:
6959 case DW_TAG_coarray_type:
6960 case DW_TAG_atomic_type:
6961 case DW_TAG_immutable_type:
6984is_canon_type_to_be_propagated_tag(
unsigned tag)
6986 bool result =
false;
6990 case DW_TAG_class_type:
6991 case DW_TAG_structure_type:
6992 case DW_TAG_union_type:
6993 case DW_TAG_subroutine_type:
6994 case DW_TAG_subprogram:
7015type_comparison_result_to_be_cached(
unsigned tag)
7020 case DW_TAG_class_type:
7021 case DW_TAG_structure_type:
7022 case DW_TAG_union_type:
7023 case DW_TAG_subroutine_type:
7024 case DW_TAG_subprogram:
7045maybe_cache_type_comparison_result(
const reader& rdr,
7050 if (!type_comparison_result_to_be_cached(tag)
7051 || (result != COMPARISON_RESULT_EQUAL
7052 && result != COMPARISON_RESULT_DIFFERENT))
7055 rdr.die_comparison_results_[p] = result;
7075get_cached_type_comparison_result(
const reader& rdr,
7079 auto i = rdr.die_comparison_results_.find(p);
7080 if (i != rdr.die_comparison_results_.end())
7103maybe_get_cached_type_comparison_result(
const reader& rdr,
7108 if (type_comparison_result_to_be_cached(tag))
7113 if (get_cached_type_comparison_result(rdr, p, result))
7125is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
7127 bool result =
false;
7128 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7130 if (!is_type_tag(tag))
7135 case DW_TAG_class_type:
7136 case DW_TAG_structure_type:
7137 case DW_TAG_union_type:
7138 result = !die_is_declaration_only(die);
7141 case DW_TAG_subroutine_type:
7142 case DW_TAG_subprogram:
7143 case DW_TAG_array_type:
7159is_decl_tag(
unsigned tag)
7163 case DW_TAG_formal_parameter:
7164 case DW_TAG_imported_declaration:
7166 case DW_TAG_unspecified_parameters:
7167 case DW_TAG_subprogram:
7168 case DW_TAG_variable:
7169 case DW_TAG_namespace:
7170 case DW_TAG_GNU_template_template_param:
7171 case DW_TAG_GNU_template_parameter_pack:
7172 case DW_TAG_GNU_formal_parameter_pack:
7184die_is_type(
const Dwarf_Die* die)
7188 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7197die_is_decl(
const Dwarf_Die* die)
7201 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7210die_is_namespace(
const Dwarf_Die* die)
7214 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
7223die_is_unspecified(Dwarf_Die* die)
7227 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7236die_is_void_type(Dwarf_Die* die)
7238 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7241 string name = die_name(die);
7254die_is_pointer_type(
const Dwarf_Die* die)
7259 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7260 if (tag == DW_TAG_pointer_type)
7274pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7276 if (!die_is_pointer_array_or_reference_type(die)
7277 && !die_is_qualified_type(die))
7280 Dwarf_Die underlying_type_die;
7281 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7284 if (!die_is_class_type(&underlying_type_die))
7287 string name = die_name(&underlying_type_die);
7289 return name.empty();
7298die_is_reference_type(
const Dwarf_Die* die)
7303 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7304 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7316die_is_array_type(
const Dwarf_Die* die)
7321 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7322 if (tag == DW_TAG_array_type)
7334die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7335{
return (die_is_pointer_type(die)
7336 || die_is_reference_type(die)
7337 || die_is_array_type(die));}
7345die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7346{
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7355die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7356{
return (die_is_pointer_array_or_reference_type(die)
7357 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7365die_is_class_type(
const Dwarf_Die* die)
7367 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7369 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7381die_is_qualified_type(
const Dwarf_Die* die)
7383 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7384 if (tag == DW_TAG_const_type
7385 || tag == DW_TAG_volatile_type
7386 || tag == DW_TAG_restrict_type)
7398die_is_function_type(
const Dwarf_Die *die)
7400 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7401 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7419die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7424 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7436die_has_children(
const Dwarf_Die* die)
7442 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7462fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die)
7467 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7468 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7471 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7473 int child_tag = dwarf_tag(&child);
7474 if (child_tag == DW_TAG_formal_parameter)
7476 memcpy(&first_parm_die, &child,
sizeof(Dwarf_Die));
7511member_fn_die_has_this_pointer(
const reader& rdr,
7512 const Dwarf_Die* die,
7513 size_t where_offset,
7514 Dwarf_Die& class_die,
7515 Dwarf_Die& object_pointer_die)
7520 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7521 if (tag != DW_TAG_subprogram && tag != DW_TAG_subroutine_type)
7524 if (tag == DW_TAG_subprogram
7525 && !die_is_at_class_scope(rdr, die, where_offset, class_die))
7528 Dwarf_Die first_parm_die;
7529 Dwarf_Die parm_type_die;
7530 if (die_has_object_pointer(die, object_pointer_die))
7536 memcpy(&first_parm_die, &object_pointer_die,
sizeof(Dwarf_Die));
7537 if (!die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7539 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7540 die_peel_typedef(&parm_type_die, parm_type_die);
7542 else if (fn_die_first_parameter_die(die, first_parm_die))
7544 memcpy(&object_pointer_die, &first_parm_die,
sizeof(Dwarf_Die));
7545 bool is_artificial =
false;
7546 if (die_flag_attribute(&first_parm_die, DW_AT_artificial, is_artificial))
7548 if (die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7550 tag = dwarf_tag(&parm_type_die);
7551 if (tag == DW_TAG_pointer_type)
7553 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7554 die_peel_typedef(&parm_type_die, parm_type_die);
7568 tag = dwarf_tag(&parm_type_die);
7569 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7571 memcpy(&class_die, &parm_type_die,
sizeof(Dwarf_Die));
7591die_this_pointer_from_object_pointer(Dwarf_Die* die,
7592 Dwarf_Die& this_pointer_die)
7595 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7597 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7612die_this_pointer_is_const(Dwarf_Die* dye)
7617 memcpy(&die, dye,
sizeof(Dwarf_Die));
7618 if (dwarf_tag(&die) == DW_TAG_const_type)
7621 if (dwarf_tag(&die) == DW_TAG_pointer_type)
7623 Dwarf_Die pointed_to_type_die;
7624 if (die_die_attribute(&die, DW_AT_type, pointed_to_type_die))
7625 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7641die_object_pointer_is_for_const_method(Dwarf_Die* die)
7644 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7646 Dwarf_Die this_pointer_die;
7647 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7648 if (die_this_pointer_is_const(&this_pointer_die))
7670die_is_at_class_scope(
const reader& rdr,
7671 const Dwarf_Die* die,
7672 size_t where_offset,
7673 Dwarf_Die& class_scope_die)
7675 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7678 int tag = dwarf_tag(&class_scope_die);
7680 return (tag == DW_TAG_structure_type
7681 || tag == DW_TAG_class_type
7682 || tag == DW_TAG_union_type);
7695die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7700 int tag = dwarf_tag(die);
7702 if (tag == DW_TAG_const_type
7703 || tag == DW_TAG_volatile_type
7704 || tag == DW_TAG_restrict_type
7705 || tag == DW_TAG_pointer_type
7706 || tag == DW_TAG_reference_type
7707 || tag == DW_TAG_rvalue_reference_type)
7709 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7715 memcpy(&peeled_die, die,
sizeof(peeled_die));
7717 while (tag == DW_TAG_const_type
7718 || tag == DW_TAG_volatile_type
7719 || tag == DW_TAG_restrict_type
7720 || tag == DW_TAG_pointer_type
7721 || tag == DW_TAG_reference_type
7722 || tag == DW_TAG_rvalue_reference_type)
7724 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7726 tag = dwarf_tag(&peeled_die);
7741die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7746 memcpy(&peeled_die, die,
sizeof(peeled_die));
7748 int tag = dwarf_tag(&peeled_die);
7750 bool result =
false;
7751 while (tag == DW_TAG_const_type
7752 || tag == DW_TAG_volatile_type
7753 || tag == DW_TAG_restrict_type)
7755 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7757 tag = dwarf_tag(&peeled_die);
7773die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7778 int tag = dwarf_tag(die);
7780 memcpy(&peeled_die, die,
sizeof(peeled_die));
7782 if (tag == DW_TAG_typedef)
7784 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7790 while (tag == DW_TAG_typedef)
7792 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7794 tag = dwarf_tag(&peeled_die);
7810die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7815 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7817 if (tag == DW_TAG_pointer_type
7818 || tag == DW_TAG_reference_type
7819 || tag == DW_TAG_rvalue_reference_type
7820 || tag == DW_TAG_typedef)
7822 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7828 while (tag == DW_TAG_pointer_type
7829 || tag == DW_TAG_reference_type
7830 || tag == DW_TAG_rvalue_reference_type
7831 || tag == DW_TAG_typedef)
7833 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7835 tag = dwarf_tag(&peeled_die);
7866die_function_type_is_method_type(
const reader& rdr,
7867 const Dwarf_Die *die,
7868 size_t where_offset,
7869 Dwarf_Die& object_pointer_die,
7870 Dwarf_Die& class_die,
7876 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7877 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7879 if (member_fn_die_has_this_pointer(rdr, die, where_offset, class_die, object_pointer_die))
7884 else if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7895 VIRTUALITY_NOT_VIRTUAL,
7897 VIRTUALITY_PURE_VIRTUAL
7910die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7916 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7918 if (v == DW_VIRTUALITY_virtual)
7919 virt = VIRTUALITY_VIRTUAL;
7920 else if (v == DW_VIRTUALITY_pure_virtual)
7921 virt = VIRTUALITY_PURE_VIRTUAL;
7923 virt = VIRTUALITY_NOT_VIRTUAL;
7935die_is_virtual(
const Dwarf_Die* die)
7938 if (!die_virtuality(die, v))
7941 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7951die_is_declared_inline(Dwarf_Die* die)
7953 uint64_t inline_value = 0;
7954 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7956 return (inline_value == DW_INL_declared_inlined
7957 || inline_value == DW_INL_declared_not_inlined);
7972slowly_compare_strings(
const Dwarf_Die *l,
7976 const char *l_str = die_char_str_attribute(l, attr_name),
7977 *r_str = die_char_str_attribute(r, attr_name);
7978 if (!l_str && !r_str)
7980 return l_str && r_str && !strcmp(l_str, r_str);
8006compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
8010 Dwarf_Attribute l_attr, r_attr;
8011 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
8012 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
8016 || l_attr.form == DW_FORM_string
8017 || l_attr.form == DW_FORM_GNU_strp_alt
8018 || form_is_DW_FORM_strx(l_attr.form)
8019 || form_is_DW_FORM_line_strp(l_attr.form));
8022 || r_attr.form == DW_FORM_string
8023 || r_attr.form == DW_FORM_GNU_strp_alt
8024 || form_is_DW_FORM_strx(r_attr.form)
8025 || form_is_DW_FORM_line_strp(r_attr.form));
8027 if ((l_attr.form == DW_FORM_strp
8028 && r_attr.form == DW_FORM_strp)
8029 || (l_attr.form == DW_FORM_GNU_strp_alt
8030 && r_attr.form == DW_FORM_GNU_strp_alt)
8031 || (form_is_DW_FORM_strx(l_attr.form)
8032 && form_is_DW_FORM_strx(r_attr.form))
8033 || (form_is_DW_FORM_line_strp(l_attr.form)
8034 && form_is_DW_FORM_line_strp(r_attr.form)))
8041 if (l_attr.valp == r_attr.valp)
8043#if WITH_DEBUG_TYPE_CANONICALIZATION
8044 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
8055 result = slowly_compare_strings(l, r, attr_name);
8073compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
8075 Dwarf_Die l_cu, r_cu;
8076 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
8077 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
8081 compare_dies_string_attribute_value(&l_cu, &r_cu,
8084 if (compared && result)
8086 Dwarf_Die peeled_l, peeled_r;
8087 if (die_is_pointer_reference_or_typedef_type(l)
8088 && die_is_pointer_reference_or_typedef_type(r)
8089 && die_peel_pointer_and_typedef(l, peeled_l)
8090 && die_peel_pointer_and_typedef(r, peeled_r))
8092 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
8093 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
8096 compare_dies_string_attribute_value(&l_cu, &r_cu,
8127die_location_expr(
const Dwarf_Die* die,
8135 Dwarf_Attribute attr;
8136 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
8140 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
8175op_pushes_constant_value(Dwarf_Op* ops,
8179 dwarf_expr_eval_context& ctxt)
8183 Dwarf_Op& op = ops[index];
8189 value = ops[index].number;
8202 value = ops[index].number;
8306 expr_result r(value);
8309 next_index = index + 1;
8339op_pushes_non_constant_value(Dwarf_Op* ops,
8343 dwarf_expr_eval_context& ctxt)
8346 Dwarf_Op& op = ops[index];
8382 next_index = index + 1;
8417 next_index = index + 1;
8421 next_index = index + 2;
8425 next_index = index + 1;
8429 next_index = index + 1;
8432 case DW_OP_GNU_variable_value:
8433 next_index = index + 1;
8440 expr_result r(
false);
8469op_manipulates_stack(Dwarf_Op* expr,
8473 dwarf_expr_eval_context& ctxt)
8475 Dwarf_Op& op = expr[index];
8481 v = ctxt.stack.front();
8486 v = ctxt.stack.front();
8505 ctxt.stack.erase(ctxt.stack.begin() + 1);
8512 ctxt.stack.erase(ctxt.stack.begin() + 2);
8517 case DW_OP_deref_size:
8525 case DW_OP_xderef_size:
8533 case DW_OP_push_object_address:
8538 case DW_OP_form_tls_address:
8539 case DW_OP_GNU_push_tls_address:
8542 if (op.atom == DW_OP_form_tls_address)
8547 case DW_OP_call_frame_cfa:
8559 if (op.atom == DW_OP_form_tls_address
8560 || op.atom == DW_OP_GNU_push_tls_address)
8561 ctxt.set_tls_address(
true);
8563 ctxt.set_tls_address(
false);
8565 next_index = index + 1;
8593op_is_arith_logic(Dwarf_Op* expr,
8597 dwarf_expr_eval_context& ctxt)
8601 Dwarf_Op& op = expr[index];
8602 expr_result val1, val2;
8603 bool result =
false;
8619 ctxt.push(val1 & val2);
8626 if (!val1.is_const())
8628 ctxt.push(val2 / val1);
8636 ctxt.push(val2 - val1);
8644 ctxt.push(val2 % val1);
8652 ctxt.push(val2 * val1);
8674 ctxt.push(val1 | val2);
8682 ctxt.push(val2 + val1);
8686 case DW_OP_plus_uconst:
8698 ctxt.push(val2 << val1);
8707 ctxt.push(val2 >> val1);
8715 ctxt.push(val2 ^ val1);
8725 if (ctxt.stack.front().is_const())
8726 ctxt.accum = ctxt.stack.front();
8728 next_index = index + 1;
8756op_is_control_flow(Dwarf_Op* expr,
8760 dwarf_expr_eval_context& ctxt)
8764 Dwarf_Op& op = expr[index];
8765 expr_result val1, val2;
8779 if (op.atom == DW_OP_eq)
8780 value = val2 == val1;
8781 else if (op.atom == DW_OP_ge)
8782 value = val2 >= val1;
8783 else if (op.atom == DW_OP_gt)
8784 value = val2 > val1;
8785 else if (op.atom == DW_OP_le)
8786 value = val2 <= val1;
8787 else if (op.atom == DW_OP_lt)
8788 value = val2 < val1;
8789 else if (op.atom == DW_OP_ne)
8790 value = val2 != val1;
8792 val1 = value ? 1 : 0;
8799 index += op.number - 1;
8804 if (val1.const_value() != 0)
8805 index += val1.const_value() - 1;
8810 case DW_OP_call_ref:
8818 if (ctxt.stack.front().is_const())
8819 ctxt.accum = ctxt.stack.front();
8821 next_index = index + 1;
8842eval_quickly(Dwarf_Op* expr,
8846 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8848 value = expr[0].number;
8875eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8878 bool& is_tls_address,
8879 dwarf_expr_eval_context &eval_ctxt)
8885 size_t index = 0, next_index = 0;
8888 if (op_is_arith_logic(expr, expr_len, index,
8889 next_index, eval_ctxt)
8890 || op_pushes_constant_value(expr, expr_len, index,
8891 next_index, eval_ctxt)
8892 || op_manipulates_stack(expr, expr_len, index,
8893 next_index, eval_ctxt)
8894 || op_pushes_non_constant_value(expr, expr_len, index,
8895 next_index, eval_ctxt)
8896 || op_is_control_flow(expr, expr_len, index,
8897 next_index, eval_ctxt))
8900 next_index = index + 1;
8904 }
while (index < expr_len);
8906 is_tls_address = eval_ctxt.set_tls_address();
8907 if (eval_ctxt.accum.is_const())
8909 value = eval_ctxt.accum;
8929eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8932 bool& is_tls_address)
8934 dwarf_expr_eval_context eval_ctxt;
8935 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8936 is_tls_address, eval_ctxt);
9128read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
9133 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
9146 uint64_t containing_anonymous_object_size = 0;
9147 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
9148 containing_anonymous_object_size));
9149 containing_anonymous_object_size *= 8;
9151 uint64_t bitfield_size = 0;
9152 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
9163 offset = containing_anonymous_object_size - off - bitfield_size;
9179die_constant_data_member_location(
const Dwarf_Die *die,
9185 Dwarf_Attribute attr;
9186 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
9187 DW_AT_data_member_location,
9192 if (dwarf_formudata(&attr, &val) != 0)
9248die_member_offset(
const reader& rdr,
9249 const Dwarf_Die* die,
9252 Dwarf_Op* expr = NULL;
9253 size_t expr_len = 0;
9254 uint64_t bit_offset = 0;
9258 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
9260 offset = bit_offset;
9272 if (!die_constant_data_member_location(die, offset))
9277 if (!die_location_expr(die, DW_AT_data_member_location,
9284 if (!eval_quickly(expr, expr_len, offset))
9286 bool is_tls_address =
false;
9287 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
9288 offset, is_tls_address,
9289 rdr.dwarf_expr_eval_ctxt()))
9307 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9308 offset += bit_offset;
9325die_location_address(Dwarf_Die* die,
9326 Dwarf_Addr& address,
9327 bool& is_tls_address)
9329 Dwarf_Op* expr = NULL;
9330 size_t expr_len = 0;
9332 is_tls_address =
false;
9337 Dwarf_Attribute attr;
9338 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
9341 if (dwarf_getlocation(&attr, &expr, &expr_len))
9348 Dwarf_Attribute result;
9349 if (!dwarf_getlocation_attr(&attr, expr, &result))
9351 return !dwarf_formaddr(&result, &address);
9354 address = expr->number;
9369die_virtual_function_index(Dwarf_Die* die,
9375 Dwarf_Op* expr = NULL;
9376 size_t expr_len = 0;
9377 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9382 bool is_tls_addr =
false;
9383 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9401 int tag = dwarf_tag(die);
9403 if (tag == DW_TAG_class_type
9404 || tag == DW_TAG_structure_type
9405 || tag == DW_TAG_union_type
9406 || tag == DW_TAG_enumeration_type)
9407 return die_is_anonymous(die);
9429get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9432 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9434 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9436 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9438 else if (tag == DW_TAG_union_type)
9440 else if (tag == DW_TAG_enumeration_type)
9459build_internal_anonymous_die_name(
const string &
base_name,
9460 size_t anonymous_type_index)
9463 if (anonymous_type_index && !
base_name.empty())
9465 std::ostringstream o;
9485get_internal_anonymous_die_name(Dwarf_Die *die,
9486 size_t anonymous_type_index)
9488 string name = get_internal_anonymous_die_prefix_name(die);
9489 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9511die_qualified_type_name(
const reader& rdr,
9512 const Dwarf_Die* die,
9513 size_t where_offset)
9518 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9519 if (tag == DW_TAG_compile_unit
9520 || tag == DW_TAG_partial_unit
9521 || tag == DW_TAG_type_unit)
9524 string name = die_name(die);
9526 Dwarf_Die scope_die;
9527 if (!get_scope_die(rdr, die, where_offset, scope_die))
9530 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9531 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9532 string separator = colon_colon ?
"::" :
".";
9538 case DW_TAG_unspecified_type:
9541 case DW_TAG_base_type:
9551 case DW_TAG_typedef:
9552 case DW_TAG_enumeration_type:
9553 case DW_TAG_structure_type:
9554 case DW_TAG_class_type:
9555 case DW_TAG_union_type:
9563 name = get_internal_anonymous_die_prefix_name(die);
9566 repr = parent_name.empty() ? name : parent_name + separator + name;
9570 case DW_TAG_const_type:
9571 case DW_TAG_volatile_type:
9572 case DW_TAG_restrict_type:
9574 Dwarf_Die underlying_type_die;
9575 bool has_underlying_type_die =
9576 die_die_attribute(die, DW_AT_type, underlying_type_die);
9578 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9581 if (tag == DW_TAG_const_type)
9583 if (has_underlying_type_die
9584 && die_is_reference_type(&underlying_type_die))
9594 else if (!has_underlying_type_die
9595 || die_is_void_type(&underlying_type_die))
9603 else if (tag == DW_TAG_volatile_type)
9605 else if (tag == DW_TAG_restrict_type)
9610 string underlying_type_repr;
9611 if (has_underlying_type_die)
9612 underlying_type_repr =
9613 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9615 underlying_type_repr =
"void";
9617 if (underlying_type_repr.empty())
9621 if (has_underlying_type_die)
9624 die_peel_qualified(&underlying_type_die, peeled);
9625 if (die_is_pointer_or_reference_type(&peeled))
9626 repr = underlying_type_repr +
" " + repr;
9628 repr +=
" " + underlying_type_repr;
9631 repr +=
" " + underlying_type_repr;
9636 case DW_TAG_pointer_type:
9637 case DW_TAG_reference_type:
9638 case DW_TAG_rvalue_reference_type:
9640 Dwarf_Die pointed_to_type_die;
9641 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9643 if (tag == DW_TAG_pointer_type)
9648 if (die_is_unspecified(&pointed_to_type_die))
9651 string pointed_type_repr =
9652 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9654 repr = pointed_type_repr;
9658 if (tag == DW_TAG_pointer_type)
9660 else if (tag == DW_TAG_reference_type)
9662 else if (tag == DW_TAG_rvalue_reference_type)
9669 case DW_TAG_subrange_type:
9682 build_subrange_type(
const_cast<reader&
>(rdr),
9685 repr += s->as_string();
9689 case DW_TAG_array_type:
9691 Dwarf_Die element_type_die;
9692 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9694 string element_type_name =
9695 die_qualified_type_name(rdr, &element_type_die, where_offset);
9696 if (element_type_name.empty())
9700 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9701 die, subranges, where_offset,
9704 repr = element_type_name;
9705 repr += array_type_def::subrange_type::vector_as_string(subranges);
9709 case DW_TAG_subroutine_type:
9710 case DW_TAG_subprogram:
9712 string return_type_name;
9714 vector<string> parm_names;
9715 bool is_const =
false;
9716 bool is_static =
false;
9718 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9720 return_type_name, class_name,
9721 parm_names, is_const,
9723 if (return_type_name.empty())
9724 return_type_name =
"void";
9726 repr = return_type_name;
9728 if (!class_name.empty())
9731 repr +=
" (" + class_name +
"::*)";
9736 for (vector<string>::const_iterator i = parm_names.begin();
9737 i != parm_names.end();
9740 if (i != parm_names.begin())
9749 case DW_TAG_string_type:
9750 case DW_TAG_ptr_to_member_type:
9751 case DW_TAG_set_type:
9752 case DW_TAG_file_type:
9753 case DW_TAG_packed_type:
9754 case DW_TAG_thrown_type:
9755 case DW_TAG_interface_type:
9756 case DW_TAG_shared_type:
9776die_qualified_decl_name(
const reader& rdr,
9777 const Dwarf_Die* die,
9778 size_t where_offset)
9780 if (!die || !die_is_decl(die))
9783 string name = die_name(die);
9785 Dwarf_Die scope_die;
9786 if (!get_scope_die(rdr, die, where_offset, scope_die))
9789 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9790 string separator =
"::";
9794 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9797 case DW_TAG_namespace:
9799 case DW_TAG_variable:
9800 repr = scope_name.empty() ? name : scope_name + separator + name;
9802 case DW_TAG_subprogram:
9803 repr = die_function_signature(rdr, die, where_offset);
9806 case DW_TAG_unspecified_parameters:
9810 case DW_TAG_formal_parameter:
9811 case DW_TAG_imported_declaration:
9812 case DW_TAG_GNU_template_template_param:
9813 case DW_TAG_GNU_template_parameter_pack:
9814 case DW_TAG_GNU_formal_parameter_pack:
9837die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9839 if (die_is_type(die))
9840 return die_qualified_type_name(rdr, die, where);
9841 else if (die_is_decl(die))
9842 return die_qualified_decl_name(rdr, die, where);
9864die_qualified_type_name_empty(
const reader& rdr,
9865 const Dwarf_Die* die,
9866 size_t where,
string &qualified_name)
9871 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9874 if (tag == DW_TAG_typedef
9875 || tag == DW_TAG_pointer_type
9876 || tag == DW_TAG_reference_type
9877 || tag == DW_TAG_rvalue_reference_type
9878 || tag == DW_TAG_array_type
9879 || tag == DW_TAG_const_type
9880 || tag == DW_TAG_volatile_type
9881 || tag == DW_TAG_restrict_type)
9883 Dwarf_Die underlying_type_die;
9884 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9887 die_qualified_type_name(rdr, &underlying_type_die, where);
9894 string name = die_qualified_type_name(rdr, die, where);
9899 qname = die_qualified_type_name(rdr, die, where);
9903 qualified_name = qname;
9943die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9944 const Dwarf_Die* die,
9945 size_t where_offset,
9947 string &return_type_name,
9949 vector<string>& parm_names,
9954 Dwarf_Die ret_type_die;
9955 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9956 return_type_name =
"void";
9960 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9961 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9963 if (return_type_name.empty())
9964 return_type_name =
"void";
9966 Dwarf_Die object_pointer_die, class_die;
9968 die_function_type_is_method_type(rdr, die, where_offset,
9970 class_die, is_static);
9975 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9977 Dwarf_Die this_pointer_die;
9978 Dwarf_Die pointed_to_die;
9980 && die_die_attribute(&object_pointer_die, DW_AT_type,
9982 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9983 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9986 string fn_name = die_name(die);
9987 string non_qualified_class_name = die_name(&class_die);
9988 bool is_ctor = fn_name == non_qualified_class_name;
9989 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9991 if (is_ctor || is_dtor)
9992 return_type_name.clear();
9995 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
9998 int child_tag = dwarf_tag(&child);
9999 if (child_tag == DW_TAG_formal_parameter)
10001 Dwarf_Die parm_type_die;
10002 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
10004 string qualified_name =
10006 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
10007 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
10009 if (qualified_name.empty())
10011 parm_names.push_back(qualified_name);
10013 else if (child_tag == DW_TAG_unspecified_parameters)
10016 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
10026 while (dwarf_siblingof(&child, &child) == 0);
10028 if (class_name.empty())
10030 Dwarf_Die parent_die;
10031 if (get_parent_die(rdr, die, parent_die, where_offset))
10033 if (die_is_class_type(&parent_die))
10035 rdr.get_die_qualified_type_name(&parent_die, where_offset);
10052die_function_signature(
const reader& rdr,
10053 const Dwarf_Die *fn_die,
10054 size_t where_offset)
10058 bool has_lang =
false;
10059 if ((has_lang = get_die_language(fn_die, lang)))
10067 string fn_name = die_linkage_name(fn_die);
10068 if (fn_name.empty())
10069 fn_name = die_name(fn_die);
10079 string return_type_name;
10080 Dwarf_Die ret_type_die;
10081 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
10082 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
10085 if (return_type_name.empty())
10086 return_type_name =
"void";
10088 Dwarf_Die scope_die;
10090 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
10091 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
10092 string fn_name = die_name(fn_die);
10093 if (!scope_name.empty())
10094 fn_name = scope_name +
"::" + fn_name;
10097 vector<string> parm_names;
10098 bool is_const =
false;
10099 bool is_static =
false;
10101 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
10103 return_type_name, class_name,
10104 parm_names, is_const, is_static);
10106 bool is_virtual = die_is_virtual(fn_die);
10108 string repr = class_name.empty() ?
"function" :
"method";
10110 repr +=
" virtual";
10112 if (!return_type_name.empty())
10113 repr +=
" " + return_type_name;
10115 repr +=
" " + fn_name;
10119 bool some_parm_emitted =
false;
10120 for (vector<string>::const_iterator i = parm_names.begin();
10121 i != parm_names.end();
10124 if (i != parm_names.begin())
10126 if (some_parm_emitted)
10130 if (!is_static && !class_name.empty())
10135 some_parm_emitted =
true;
10166die_pretty_print_type(reader& rdr,
10167 const Dwarf_Die* die,
10168 size_t where_offset)
10171 || (!die_is_type(die)
10172 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
10177 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10180 case DW_TAG_string_type:
10189 repr =
"string type";
10191 case DW_TAG_unspecified_type:
10192 case DW_TAG_ptr_to_member_type:
10195 case DW_TAG_namespace:
10196 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
10199 case DW_TAG_base_type:
10200 repr = rdr.get_die_qualified_type_name(die, where_offset);
10203 case DW_TAG_typedef:
10205 string qualified_name;
10206 if (!die_qualified_type_name_empty(rdr, die,
10209 repr =
"typedef " + qualified_name;
10213 case DW_TAG_const_type:
10214 case DW_TAG_volatile_type:
10215 case DW_TAG_restrict_type:
10216 case DW_TAG_pointer_type:
10217 case DW_TAG_reference_type:
10218 case DW_TAG_rvalue_reference_type:
10219 repr = rdr.get_die_qualified_type_name(die, where_offset);
10222 case DW_TAG_enumeration_type:
10224 string qualified_name =
10225 rdr.get_die_qualified_type_name(die, where_offset);
10226 repr =
"enum " + qualified_name;
10230 case DW_TAG_structure_type:
10231 case DW_TAG_class_type:
10233 string qualified_name =
10234 rdr.get_die_qualified_type_name(die, where_offset);
10235 repr =
"class " + qualified_name;
10239 case DW_TAG_union_type:
10241 string qualified_name =
10242 rdr.get_die_qualified_type_name(die, where_offset);
10243 repr =
"union " + qualified_name;
10247 case DW_TAG_array_type:
10249 Dwarf_Die element_type_die;
10250 if (!die_die_attribute(die, DW_AT_type, element_type_die))
10252 string element_type_name =
10253 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
10254 if (element_type_name.empty())
10258 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
10261 repr = element_type_name;
10262 repr += array_type_def::subrange_type::vector_as_string(subranges);
10266 case DW_TAG_subrange_type:
10276 repr += die_qualified_type_name(rdr, die, where_offset);
10280 case DW_TAG_subroutine_type:
10281 case DW_TAG_subprogram:
10283 string return_type_name;
10285 vector<string> parm_names;
10286 bool is_const =
false;
10287 bool is_static =
false;
10289 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10291 return_type_name, class_name,
10292 parm_names, is_const,
10294 if (class_name.empty())
10295 repr =
"function type";
10297 repr =
"method type";
10298 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
10302 case DW_TAG_set_type:
10303 case DW_TAG_file_type:
10304 case DW_TAG_packed_type:
10305 case DW_TAG_thrown_type:
10306 case DW_TAG_interface_type:
10307 case DW_TAG_shared_type:
10333die_pretty_print_decl(reader& rdr,
10334 const Dwarf_Die* die,
10335 size_t where_offset)
10337 if (!die || !die_is_decl(die))
10342 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10345 case DW_TAG_namespace:
10346 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
10349 case DW_TAG_member:
10350 case DW_TAG_variable:
10352 string type_repr =
"void";
10353 Dwarf_Die type_die;
10354 if (die_die_attribute(die, DW_AT_type, type_die))
10355 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
10356 repr = die_qualified_name(rdr, die, where_offset);
10358 repr = type_repr +
" " + repr;
10362 case DW_TAG_subprogram:
10363 repr = die_function_signature(rdr, die, where_offset);
10389die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10391 if (die_is_type(die))
10392 return die_pretty_print_type(rdr, die, where_offset);
10393 else if (die_is_decl(die))
10394 return die_pretty_print_decl(rdr, die, where_offset);
10417compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10421 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10422 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10423 if (l_tag != r_tag)
10426 bool result =
false;
10428 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10431 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10433 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10440 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10450 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10467at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10468 const Dwarf_Die *l,
10469 const Dwarf_Die *r)
10471 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10474 if ((die_is_declaration_only(l) && die_has_no_child(l))
10475 || (die_is_declaration_only(r) && die_has_no_child(r)))
10502compare_as_type_dies(
const reader& rdr,
10503 const Dwarf_Die *l,
10504 const Dwarf_Die *r)
10510 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
10511 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
10512 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10513 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
10521 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10526 uint64_t l_size = 0, r_size = 0;
10527 die_size_in_bits(l, l_size);
10528 die_size_in_bits(r, r_size);
10530 return l_size == r_size;
10545compare_as_decl_and_type_dies(
const reader &rdr,
10546 const Dwarf_Die *l,
10547 const Dwarf_Die *r)
10549 if (!compare_as_decl_dies(l, r)
10550 || !compare_as_type_dies(rdr, l, r))
10572fn_die_equal_by_linkage_name(
const Dwarf_Die *l,
10573 const Dwarf_Die *r)
10581 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10583 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10586 string lname = die_name(l), rname = die_name(r);
10587 string llinkage_name = die_linkage_name(l),
10588 rlinkage_name = die_linkage_name(r);
10590 if (die_is_in_c_or_cplusplus(l)
10591 && die_is_in_c_or_cplusplus(r))
10593 if (!llinkage_name.empty() && !rlinkage_name.empty())
10594 return llinkage_name == rlinkage_name;
10595 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10598 return lname == rname;
10601 return (!llinkage_name.empty()
10602 && !rlinkage_name.empty()
10603 && llinkage_name == rlinkage_name);
10635try_canonical_die_comparison(
const reader& rdr,
10636 Dwarf_Off l_offset, Dwarf_Off r_offset,
10638 bool& l_has_canonical_die_offset,
10639 bool& r_has_canonical_die_offset,
10640 Dwarf_Off& l_canonical_die_offset,
10641 Dwarf_Off& r_canonical_die_offset,
10644#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10645 if (rdr.debug_die_canonicalization_is_on_
10646 && !rdr.use_canonical_die_comparison_)
10651 l_has_canonical_die_offset =
10652 (l_canonical_die_offset =
10653 rdr.get_canonical_die_offset(l_offset, l_die_source,
10656 r_has_canonical_die_offset =
10657 (r_canonical_die_offset =
10658 rdr.get_canonical_die_offset(r_offset, r_die_source,
10661 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10663 result = (l_canonical_die_offset == r_canonical_die_offset);
10670#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10683notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10687#define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10688 notify_die_comparison_failed(l, r)
10690#define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10703#define ABG_RETURN(value) \
10706 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10708 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10710 return return_comparison_result(l, r, dies_being_compared, \
10711 value, aggregates_being_compared, \
10712 update_canonical_dies_on_the_fly); \
10723#define ABG_RETURN_FALSE \
10726 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10727 return return_comparison_result(l, r, dies_being_compared, \
10728 COMPARISON_RESULT_DIFFERENT, \
10729 aggregates_being_compared, \
10730 update_canonical_dies_on_the_fly); \
10745#define SET_RESULT_TO_FALSE(result, l , r) \
10748 result = COMPARISON_RESULT_DIFFERENT; \
10749 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10765#define SET_RESULT_TO(result, value, l , r) \
10768 result = (value); \
10769 if (result == COMPARISON_RESULT_DIFFERENT) \
10771 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10775#define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10778 if (aggregates_being_compared.contains(dies_being_compared)) \
10780 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10781 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10782 ABG_RETURN(result); \
10797get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10802 bool found_member =
false;
10803 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
10806 found_member = (dwarf_siblingof(member, member) == 0))
10808 int tag = dwarf_tag(member);
10809 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10813 return found_member;
10827get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10832 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10834 || tag == DW_TAG_union_type
10835 || tag == DW_TAG_class_type);
10837 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die),
10843 tag = dwarf_tag(child);
10845 if (!(tag == DW_TAG_member
10846 || tag == DW_TAG_inheritance
10847 || tag == DW_TAG_subprogram))
10848 found_child = get_next_member_sibling_die(child, child);
10850 return found_child;
10873maybe_propagate_canonical_type(
const reader& rdr,
10874 const Dwarf_Die* l,
10875 const Dwarf_Die* r)
10877 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10878 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10880 if (l_tag != r_tag)
10883 if (is_canon_type_to_be_propagated_tag(l_tag))
10884 propagate_canonical_type(rdr, l, r);
10902propagate_canonical_type(
const reader& rdr,
10903 const Dwarf_Die* l,
10904 const Dwarf_Die* r)
10913 const die_source l_source = rdr.get_die_source(l);
10914 const die_source r_source = rdr.get_die_source(r);
10916 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
10917 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
10918 bool l_has_canonical_die_offset =
false;
10919 bool r_has_canonical_die_offset =
false;
10920 Dwarf_Off l_canonical_die_offset = 0;
10921 Dwarf_Off r_canonical_die_offset = 0;
10923 l_has_canonical_die_offset =
10924 (l_canonical_die_offset =
10925 rdr.get_canonical_die_offset(l_offset, l_source,
10928 r_has_canonical_die_offset =
10929 (r_canonical_die_offset =
10930 rdr.get_canonical_die_offset(r_offset, r_source,
10934 if (!l_has_canonical_die_offset
10935 && r_has_canonical_die_offset
10938 && l_source == r_source)
10941 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10943 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10944 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10945 rdr.canonical_propagated_count_++;
10983return_comparison_result(
const Dwarf_Die* l,
10984 const Dwarf_Die* r,
10987 offset_pairs_stack_type& comparison_stack,
10988 bool do_propagate_canonical_type =
true)
10990 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10992 if (result == COMPARISON_RESULT_EQUAL)
10997 if (do_propagate_canonical_type)
11000 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
11006 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
11019 else if (result == COMPARISON_RESULT_UNKNOWN)
11060 if (comparison_stack.is_redundant(cur_dies)
11061 && comparison_stack.vect_.back() == cur_dies)
11065 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
11066 comparison_stack.confirm_canonical_propagated_type(cur_dies);
11068 result = COMPARISON_RESULT_EQUAL;
11070 else if (is_canon_type_to_be_propagated_tag(l_tag)
11071 && comparison_stack.vect_.back() == cur_dies)
11076 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
11077 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
11081 else if (result == COMPARISON_RESULT_DIFFERENT)
11098 if (comparison_stack.is_redundant(cur_dies)
11099 && comparison_stack.vect_.back() == cur_dies)
11100 comparison_stack.cancel_canonical_propagated_type(cur_dies);
11108 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
11109 result = COMPARISON_RESULT_UNKNOWN;
11110 else if (is_canon_type_to_be_propagated_tag(l_tag)
11111 && !comparison_stack.vect_.empty()
11112 && comparison_stack.vect_.back() == cur_dies)
11117 comparison_stack.erase(cur_dies);
11119 maybe_cache_type_comparison_result(comparison_stack.rdr_,
11120 l_tag, cur_dies, result);
11149compare_dies(
const reader& rdr,
11150 const Dwarf_Die *l,
const Dwarf_Die *r,
11151 offset_pairs_stack_type& aggregates_being_compared,
11152 bool update_canonical_dies_on_the_fly)
11157 const die_source l_die_source = rdr.get_die_source(l);
11158 const die_source r_die_source = rdr.get_die_source(r);
11160 offset_type l_offset =
11163 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11166 offset_type r_offset =
11169 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11174 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
11175 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11177 if (l_tag != r_tag)
11180 if (l_offset == r_offset)
11181 return COMPARISON_RESULT_EQUAL;
11183 if (rdr.leverage_dwarf_factorization()
11184 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
11185 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
11186 if (l_offset != r_offset)
11187 return COMPARISON_RESULT_DIFFERENT;
11190 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
11191 dies_being_compared,
11195 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
11196 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
11200 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
11202 bool canonical_compare_result =
false;
11203 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
11204 l_die_source, r_die_source,
11205 l_has_canonical_die_offset,
11206 r_has_canonical_die_offset,
11207 l_canonical_die_offset,
11208 r_canonical_die_offset,
11209 canonical_compare_result))
11213 (canonical_compare_result
11214 ? COMPARISON_RESULT_EQUAL
11215 : COMPARISON_RESULT_DIFFERENT),
11225 case DW_TAG_base_type:
11226 case DW_TAG_string_type:
11227 case DW_TAG_unspecified_type:
11228 if (!compare_as_decl_and_type_dies(rdr, l, r))
11232 case DW_TAG_typedef:
11233 case DW_TAG_pointer_type:
11234 case DW_TAG_reference_type:
11235 case DW_TAG_rvalue_reference_type:
11236 case DW_TAG_const_type:
11237 case DW_TAG_volatile_type:
11238 case DW_TAG_restrict_type:
11240 if (!compare_as_type_dies(rdr, l, r))
11246 bool from_the_same_tu =
false;
11247 if (!pointer_or_qual_die_of_anonymous_class_type(l)
11248 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
11249 && from_the_same_tu)
11266 Dwarf_Die lu_type_die, ru_type_die;
11267 bool lu_is_void, ru_is_void;
11269 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
11270 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
11272 if (lu_is_void && ru_is_void)
11273 result = COMPARISON_RESULT_EQUAL;
11274 else if (lu_is_void != ru_is_void)
11277 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
11278 aggregates_being_compared,
11279 update_canonical_dies_on_the_fly);
11283 case DW_TAG_enumeration_type:
11284 if (!compare_as_decl_and_type_dies(rdr, l, r))
11289 Dwarf_Die l_enumtor, r_enumtor;
11290 bool found_l_enumtor =
true, found_r_enumtor =
true;
11292 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11293 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11295 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11297 found_l_enumtor && found_r_enumtor;
11298 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
11299 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
11301 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
11302 if ( l_tag != r_tag)
11308 if (l_tag != DW_TAG_enumerator)
11311 uint64_t l_val = 0, r_val = 0;
11312 die_unsigned_constant_attribute(&l_enumtor,
11315 die_unsigned_constant_attribute(&r_enumtor,
11318 if (l_val != r_val)
11324 if (found_l_enumtor != found_r_enumtor )
11329 case DW_TAG_structure_type:
11330 case DW_TAG_union_type:
11331 case DW_TAG_class_type:
11333 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11335 rdr.compare_count_++;
11337 if (!compare_as_decl_and_type_dies(rdr, l, r))
11339 else if (rdr.options().assume_odr_for_cplusplus
11340 && rdr.odr_is_relevant(l)
11341 && rdr.odr_is_relevant(r)
11342 && !die_is_anonymous(l)
11343 && !die_is_anonymous(r))
11344 result = COMPARISON_RESULT_EQUAL;
11347 aggregates_being_compared.add(dies_being_compared);
11349 Dwarf_Die l_member, r_member;
11350 bool found_l_member =
true, found_r_member =
true;
11352 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11353 for (found_l_member = get_member_child_die(l, &l_member),
11354 found_r_member = get_member_child_die(r, &r_member);
11355 found_l_member && found_r_member;
11356 found_l_member = get_next_member_sibling_die(&l_member,
11358 found_r_member = get_next_member_sibling_die(&r_member,
11361 int l_tag = dwarf_tag(&l_member),
11362 r_tag = dwarf_tag(&r_member);
11364 if (l_tag != r_tag)
11371 || l_tag == DW_TAG_variable
11372 || l_tag == DW_TAG_inheritance
11373 || l_tag == DW_TAG_subprogram);
11376 compare_dies(rdr, &l_member, &r_member,
11377 aggregates_being_compared,
11378 update_canonical_dies_on_the_fly);
11380 if (local_result == COMPARISON_RESULT_UNKNOWN)
11389 result = local_result;
11391 if (local_result == COMPARISON_RESULT_DIFFERENT)
11397 if (found_l_member != found_r_member)
11406 case DW_TAG_array_type:
11408 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11410 aggregates_being_compared.add(dies_being_compared);
11412 rdr.compare_count_++;
11414 Dwarf_Die l_child, r_child;
11415 bool found_l_child, found_r_child;
11416 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11418 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11420 found_l_child && found_r_child;
11421 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11422 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11424 int l_child_tag = dwarf_tag(&l_child),
11425 r_child_tag = dwarf_tag(&r_child);
11426 if (l_child_tag == DW_TAG_subrange_type
11427 || r_child_tag == DW_TAG_subrange_type)
11429 result = compare_dies(rdr, &l_child, &r_child,
11430 aggregates_being_compared,
11431 update_canonical_dies_on_the_fly);
11439 if (found_l_child != found_r_child)
11442 Dwarf_Die ltype_die, rtype_die;
11443 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11444 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11447 result = compare_dies(rdr, <ype_die, &rtype_die,
11448 aggregates_being_compared,
11449 update_canonical_dies_on_the_fly);
11455 case DW_TAG_subrange_type:
11457 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11458 l_upper_bound = 0, r_upper_bound = 0;
11459 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11460 l_upper_bound_set =
false, r_upper_bound_set =
false;
11462 l_lower_bound_set =
11463 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11464 r_lower_bound_set =
11465 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11467 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11470 uint64_t l_count = 0;
11471 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11473 l_upper_bound = l_lower_bound + l_count;
11474 l_upper_bound_set =
true;
11480 l_upper_bound_set =
true;
11482 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11485 uint64_t r_count = 0;
11486 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11488 r_upper_bound = r_lower_bound + r_count;
11489 r_upper_bound_set =
true;
11495 r_upper_bound_set =
true;
11497 if ((l_lower_bound_set != r_lower_bound_set)
11498 || (l_upper_bound_set != r_upper_bound_set)
11499 || (l_lower_bound != r_lower_bound)
11500 || (l_upper_bound != r_upper_bound))
11505 case DW_TAG_subroutine_type:
11506 case DW_TAG_subprogram:
11508 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11510 aggregates_being_compared.add(dies_being_compared);
11512 rdr.compare_count_++;
11514 if (l_tag == DW_TAG_subprogram
11515 && !fn_die_equal_by_linkage_name(l, r))
11520 else if (l_tag == DW_TAG_subprogram
11521 && die_is_in_c(l) && die_is_in_c(r))
11523 result = COMPARISON_RESULT_EQUAL;
11526 else if (!die_is_in_c(l) && !die_is_in_c(r))
11532 Dwarf_Die l_return_type, r_return_type;
11533 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11535 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11537 if (l_return_type_is_void != r_return_type_is_void
11538 || (!l_return_type_is_void
11539 && !compare_dies(rdr,
11540 &l_return_type, &r_return_type,
11541 aggregates_being_compared,
11542 update_canonical_dies_on_the_fly)))
11546 Dwarf_Die l_child, r_child;
11547 bool found_l_child, found_r_child;
11548 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11550 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11552 found_l_child && found_r_child;
11553 found_l_child = dwarf_siblingof(&l_child,
11555 found_r_child = dwarf_siblingof(&r_child,
11558 int l_child_tag = dwarf_tag(&l_child);
11559 int r_child_tag = dwarf_tag(&r_child);
11561 COMPARISON_RESULT_EQUAL;
11562 if (l_child_tag != r_child_tag)
11563 local_result = COMPARISON_RESULT_DIFFERENT;
11564 if (l_child_tag == DW_TAG_formal_parameter)
11566 compare_dies(rdr, &l_child, &r_child,
11567 aggregates_being_compared,
11568 update_canonical_dies_on_the_fly);
11569 if (local_result == COMPARISON_RESULT_DIFFERENT)
11571 result = local_result;
11575 if (local_result == COMPARISON_RESULT_UNKNOWN)
11586 result = local_result;
11588 if (found_l_child != found_r_child)
11598 case DW_TAG_formal_parameter:
11600 Dwarf_Die l_type, r_type;
11601 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11602 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11603 if (l_type_is_void != r_type_is_void)
11605 else if (!l_type_is_void)
11608 compare_dies(rdr, &l_type, &r_type,
11609 aggregates_being_compared,
11610 update_canonical_dies_on_the_fly);
11616 case DW_TAG_variable:
11617 case DW_TAG_member:
11618 if (compare_as_decl_dies(l, r))
11621 if (l_tag == DW_TAG_member)
11623 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11624 die_member_offset(rdr, l, l_offset_in_bits);
11625 die_member_offset(rdr, r, r_offset_in_bits);
11626 if (l_offset_in_bits != r_offset_in_bits)
11632 Dwarf_Die l_type, r_type;
11633 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11634 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11636 compare_dies(rdr, &l_type, &r_type,
11637 aggregates_being_compared,
11638 update_canonical_dies_on_the_fly);
11646 case DW_TAG_inheritance:
11648 Dwarf_Die l_type, r_type;
11649 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11650 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11651 result = compare_dies(rdr, &l_type, &r_type,
11652 aggregates_being_compared,
11653 update_canonical_dies_on_the_fly);
11657 uint64_t l_a = 0, r_a = 0;
11658 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11659 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11663 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11664 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11668 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11669 die_member_offset(rdr, l, l_offset_in_bits);
11670 die_member_offset(rdr, r, r_offset_in_bits);
11671 if (l_offset_in_bits != r_offset_in_bits)
11676 case DW_TAG_ptr_to_member_type:
11678 bool comp_result =
false;
11679 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11683 Dwarf_Die l_type, r_type;
11684 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11685 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11686 result = compare_dies(rdr, &l_type, &r_type,
11687 aggregates_being_compared,
11688 update_canonical_dies_on_the_fly);
11692 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11693 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11694 result = compare_dies(rdr, &l_type, &r_type,
11695 aggregates_being_compared,
11696 update_canonical_dies_on_the_fly);
11702 case DW_TAG_enumerator:
11703 case DW_TAG_packed_type:
11704 case DW_TAG_set_type:
11705 case DW_TAG_file_type:
11706 case DW_TAG_thrown_type:
11707 case DW_TAG_interface_type:
11708 case DW_TAG_shared_type:
11709 case DW_TAG_compile_unit:
11710 case DW_TAG_namespace:
11711 case DW_TAG_module:
11712 case DW_TAG_constant:
11713 case DW_TAG_partial_unit:
11714 case DW_TAG_imported_unit:
11715 case DW_TAG_dwarf_procedure:
11716 case DW_TAG_imported_declaration:
11717 case DW_TAG_entry_point:
11719 case DW_TAG_lexical_block:
11720 case DW_TAG_unspecified_parameters:
11721 case DW_TAG_variant:
11722 case DW_TAG_common_block:
11723 case DW_TAG_common_inclusion:
11724 case DW_TAG_inlined_subroutine:
11725 case DW_TAG_with_stmt:
11726 case DW_TAG_access_declaration:
11727 case DW_TAG_catch_block:
11728 case DW_TAG_friend:
11729 case DW_TAG_namelist:
11730 case DW_TAG_namelist_item:
11731 case DW_TAG_template_type_parameter:
11732 case DW_TAG_template_value_parameter:
11733 case DW_TAG_try_block:
11734 case DW_TAG_variant_part:
11735 case DW_TAG_imported_module:
11736 case DW_TAG_condition:
11737 case DW_TAG_type_unit:
11738 case DW_TAG_template_alias:
11739 case DW_TAG_lo_user:
11740 case DW_TAG_MIPS_loop:
11741 case DW_TAG_format_label:
11742 case DW_TAG_function_template:
11743 case DW_TAG_class_template:
11744 case DW_TAG_GNU_BINCL:
11745 case DW_TAG_GNU_EINCL:
11746 case DW_TAG_GNU_template_template_param:
11747 case DW_TAG_GNU_template_parameter_pack:
11748 case DW_TAG_GNU_formal_parameter_pack:
11749 case DW_TAG_GNU_call_site:
11750 case DW_TAG_GNU_call_site_parameter:
11751 case DW_TAG_hi_user:
11752#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11753 if (rdr.debug_die_canonicalization_is_on_)
11780compare_dies(
const reader& rdr,
11781 const Dwarf_Die *l,
11782 const Dwarf_Die *r,
11783 bool update_canonical_dies_on_the_fly)
11785 offset_pairs_stack_type aggregates_being_compared(rdr);
11786 return compare_dies(rdr, l, r, aggregates_being_compared,
11787 update_canonical_dies_on_the_fly);
11809compare_dies_during_canonicalization(reader& rdr,
11810 const Dwarf_Die *l,
11811 const Dwarf_Die *r,
11812 bool update_canonical_dies_on_the_fly)
11814#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11815 if (rdr.debug_die_canonicalization_is_on_)
11817 bool canonical_equality =
false, structural_equality =
false;
11818 rdr.use_canonical_die_comparison_ =
false;
11819 structural_equality = compare_dies(rdr, l, r,
11821 rdr.use_canonical_die_comparison_ =
true;
11822 canonical_equality = compare_dies(rdr, l, r,
11823 update_canonical_dies_on_the_fly);
11824 if (canonical_equality != structural_equality)
11826 std::cerr <<
"structural & canonical equality different for DIEs: "
11828 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11829 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11832 << rdr.get_die_pretty_type_representation(l, 0)
11837 return structural_equality;
11840 return compare_dies(rdr, l, r,
11841 update_canonical_dies_on_the_fly);
11883find_import_unit_point_between_dies(
const reader& rdr,
11884 size_t partial_unit_offset,
11885 Dwarf_Off first_die_offset,
11886 Dwarf_Off first_die_cu_offset,
11888 size_t last_die_offset,
11889 size_t& imported_point_offset)
11892 rdr.tu_die_imported_unit_points_map(source);
11894 tu_die_imported_unit_points_map_type::const_iterator iter =
11895 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11897 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11900 if (imported_unit_points.empty())
11903 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11904 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11906 find_lower_bound_in_imported_unit_points(imported_unit_points,
11910 if (last_die_offset !=
static_cast<size_t>(-1))
11911 find_lower_bound_in_imported_unit_points(imported_unit_points,
11915 if (e != imported_unit_points.end())
11917 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11918 if (i->imported_unit_die_off == partial_unit_offset)
11920 imported_point_offset = i->offset_of_import ;
11924 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11926 if (find_import_unit_point_between_dies(rdr,
11927 partial_unit_offset,
11928 i->imported_unit_child_off,
11929 i->imported_unit_cu_off,
11930 i->imported_unit_die_source,
11932 imported_point_offset))
11938 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11939 if (i->imported_unit_die_off == partial_unit_offset)
11941 imported_point_offset = i->offset_of_import ;
11945 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11947 if (find_import_unit_point_between_dies(rdr,
11948 partial_unit_offset,
11949 i->imported_unit_child_off,
11950 i->imported_unit_cu_off,
11951 i->imported_unit_die_source,
11953 imported_point_offset))
11986find_import_unit_point_before_die(
const reader& rdr,
11987 size_t partial_unit_offset,
11988 size_t where_offset,
11989 size_t& imported_point_offset)
11991 size_t import_point_offset = 0;
11992 Dwarf_Die first_die_of_tu;
11994 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
11995 &first_die_of_tu) != 0)
11998 Dwarf_Die cu_die_memory;
12001 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
12002 &cu_die_memory, 0, 0);
12004 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
12005 dwarf_dieoffset(&first_die_of_tu),
12006 dwarf_dieoffset(cu_die),
12007 PRIMARY_DEBUG_INFO_DIE_SOURCE,
12009 import_point_offset))
12011 imported_point_offset = import_point_offset;
12015 if (import_point_offset)
12017 imported_point_offset = import_point_offset;
12045get_parent_die(
const reader& rdr,
12046 const Dwarf_Die* die,
12047 Dwarf_Die& parent_die,
12048 size_t where_offset)
12052 const die_source source = rdr.get_die_source(die);
12055 offset_offset_map_type::const_iterator i =
12056 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
12063 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
12064 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
12065 i->second, &parent_die));
12067 case ALT_DEBUG_INFO_DIE_SOURCE:
12068 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
12069 i->second, &parent_die));
12071 case TYPE_UNIT_DIE_SOURCE:
12072 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
12073 i->second, &parent_die));
12075 case NO_DEBUG_INFO_DIE_SOURCE:
12076 case NUMBER_OF_DIE_SOURCES:
12080 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
12082 if (where_offset == 0)
12084 parent_die = *rdr.cur_tu_die();
12087 size_t import_point_offset = 0;
12089 find_import_unit_point_before_die(rdr,
12090 dwarf_dieoffset(&parent_die),
12092 import_point_offset);
12098 parent_die = *rdr.cur_tu_die();
12102 Dwarf_Die import_point_die;
12103 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
12104 import_point_offset,
12105 &import_point_die));
12106 return get_parent_die(rdr, &import_point_die,
12107 parent_die, where_offset);
12140get_scope_die(
const reader& rdr,
12141 const Dwarf_Die* dye,
12142 size_t where_offset,
12143 Dwarf_Die& scope_die)
12145 Dwarf_Die origin_die_mem;
12146 Dwarf_Die *die = &origin_die_mem;
12147 if (!die_origin_die(dye, origin_die_mem))
12148 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
12151 get_die_language(die, die_lang);
12153 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
12155 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
12156 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
12159 if (!get_parent_die(rdr, die, scope_die, where_offset))
12162 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
12163 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
12164 || dwarf_tag(&scope_die) == DW_TAG_array_type)
12165 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
12195get_scope_for_die(reader& rdr,
12197 bool called_for_public_decl,
12198 size_t where_offset)
12200 Dwarf_Die origin_die_mem;
12201 Dwarf_Die *die = &origin_die_mem;
12203 if (!die_origin_die(dye, origin_die_mem))
12206 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
12208 const die_source source_of_die = rdr.get_die_source(die);
12211 get_die_language(die, die_lang);
12213 || rdr.die_parent_map(source_of_die).empty())
12218 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
12219 return rdr.global_scope();
12222 Dwarf_Die parent_die;
12224 if (!get_parent_die(rdr, die, parent_die, where_offset))
12225 return rdr.nil_scope();
12227 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
12228 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
12229 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
12231 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
12232 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
12234 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
12235 || source_of_die == TYPE_UNIT_DIE_SOURCE);
12236 return rdr.cur_transl_unit()->get_global_scope();
12245 die_tu_map_type::const_iterator i =
12246 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
12247 if (i != rdr.die_tu_map().end())
12248 return i->second->get_global_scope();
12249 return rdr.cur_transl_unit()->get_global_scope();
12254 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
12255 || dwarf_tag(&parent_die) == DW_TAG_array_type
12256 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
12268 called_for_public_decl,
12277 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
12278 return rdr.nil_scope();
12279 s = get_scope_for_die(rdr, &parent_die,
12280 called_for_public_decl,
12286 d = build_ir_node_from_die(rdr, &parent_die,
12287 called_for_public_decl,
12289 s = dynamic_pointer_cast<scope_decl>(d);
12293 return rdr.nil_scope();
12296 if (cl && cl->get_is_declaration_only())
12299 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
12316dwarf_language_to_tu_language(
size_t l)
12321 return translation_unit::LANG_C89;
12323 return translation_unit::LANG_C;
12324 case DW_LANG_Ada83:
12325 return translation_unit::LANG_Ada83;
12326 case DW_LANG_C_plus_plus:
12327 return translation_unit::LANG_C_plus_plus;
12328 case DW_LANG_Cobol74:
12329 return translation_unit::LANG_Cobol74;
12330 case DW_LANG_Cobol85:
12331 return translation_unit::LANG_Cobol85;
12332 case DW_LANG_Fortran77:
12333 return translation_unit::LANG_Fortran77;
12334 case DW_LANG_Fortran90:
12335 return translation_unit::LANG_Fortran90;
12336 case DW_LANG_Pascal83:
12337 return translation_unit::LANG_Pascal83;
12338 case DW_LANG_Modula2:
12339 return translation_unit::LANG_Modula2;
12341 return translation_unit::LANG_Java;
12343 return translation_unit::LANG_C99;
12344 case DW_LANG_Ada95:
12345 return translation_unit::LANG_Ada95;
12346 case DW_LANG_Fortran95:
12347 return translation_unit::LANG_Fortran95;
12349 return translation_unit::LANG_PLI;
12351 return translation_unit::LANG_ObjC;
12352 case DW_LANG_ObjC_plus_plus:
12353 return translation_unit::LANG_ObjC_plus_plus;
12355#ifdef HAVE_DW_LANG_Rust_enumerator
12357 return translation_unit::LANG_Rust;
12360#ifdef HAVE_DW_LANG_UPC_enumerator
12362 return translation_unit::LANG_UPC;
12365#ifdef HAVE_DW_LANG_D_enumerator
12367 return translation_unit::LANG_D;
12370#ifdef HAVE_DW_LANG_Python_enumerator
12371 case DW_LANG_Python:
12372 return translation_unit::LANG_Python;
12375#ifdef HAVE_DW_LANG_Go_enumerator
12377 return translation_unit::LANG_Go;
12380#ifdef HAVE_DW_LANG_C11_enumerator
12382 return translation_unit::LANG_C11;
12385#ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12386 case DW_LANG_C_plus_plus_03:
12387 return translation_unit::LANG_C_plus_plus_03;
12390#ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12391 case DW_LANG_C_plus_plus_11:
12392 return translation_unit::LANG_C_plus_plus_11;
12395#ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12396 case DW_LANG_C_plus_plus_14:
12397 return translation_unit::LANG_C_plus_plus_14;
12400#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12401 case DW_LANG_Mips_Assembler:
12402 return translation_unit::LANG_Mips_Assembler;
12406 return translation_unit::LANG_UNKNOWN;
12423 case translation_unit::LANG_UNKNOWN:
12426 case translation_unit::LANG_Cobol74:
12427 case translation_unit::LANG_Cobol85:
12430 case translation_unit::LANG_C89:
12431 case translation_unit::LANG_C99:
12432 case translation_unit::LANG_C11:
12433 case translation_unit::LANG_C:
12434 case translation_unit::LANG_C_plus_plus_03:
12435 case translation_unit::LANG_C_plus_plus_11:
12436 case translation_unit::LANG_C_plus_plus_14:
12437 case translation_unit::LANG_C_plus_plus:
12438 case translation_unit::LANG_ObjC:
12439 case translation_unit::LANG_ObjC_plus_plus:
12440 case translation_unit::LANG_Rust:
12443 case translation_unit::LANG_Fortran77:
12444 case translation_unit::LANG_Fortran90:
12445 case translation_unit::LANG_Fortran95:
12446 case translation_unit::LANG_Ada83:
12447 case translation_unit::LANG_Ada95:
12448 case translation_unit::LANG_Pascal83:
12449 case translation_unit::LANG_Modula2:
12452 case translation_unit::LANG_Java:
12455 case translation_unit::LANG_PLI:
12458 case translation_unit::LANG_UPC:
12459 case translation_unit::LANG_D:
12460 case translation_unit::LANG_Python:
12461 case translation_unit::LANG_Go:
12462 case translation_unit::LANG_Mips_Assembler:
12489 imported_unit_points_type::const_iterator& r)
12491 imported_unit_point v(val);
12492 imported_unit_points_type::const_iterator result =
12493 std::lower_bound(p.begin(), p.end(), v);
12495 bool is_ok = result != p.end();
12517build_translation_unit_and_add_to_ir(reader& rdr,
12525 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12529 rdr.clear_per_translation_unit_data();
12531 rdr.cur_tu_die(die);
12533 string path = die_string_attribute(die, DW_AT_name);
12534 if (path ==
"<artificial>")
12540 std::ostringstream o;
12541 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12544 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12554 const string& abs_path =
12555 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12556 result = rdr.corpus()->find_translation_unit(abs_path);
12561 result.reset(
new translation_unit(rdr.env(),
12564 result->set_compilation_dir_path(compilation_dir);
12565 rdr.corpus()->add(result);
12567 die_unsigned_constant_attribute(die, DW_AT_language, l);
12568 result->set_language(dwarf_language_to_tu_language(l));
12571 rdr.cur_transl_unit(result);
12572 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12575 if (dwarf_child(die, &child) != 0)
12578 result->set_is_constructed(
false);
12579 int tag = dwarf_tag(&child);
12581 if (rdr.load_undefined_interfaces()
12582 && (rdr.is_decl_die_with_undefined_symbol(&child)
12583 || tag == DW_TAG_class_type
12588 || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
12589 && die_is_in_cplus_plus(&child))))
12593 build_ir_node_from_die(rdr, &child,
12598 dwarf_dieoffset(&child));
12600 else if (!rdr.env().analyze_exported_interfaces_only()
12601 || rdr.is_decl_die_with_exported_symbol(&child))
12605 build_ir_node_from_die(rdr, &child,
12606 die_is_public_decl(&child),
12607 dwarf_dieoffset(&child));
12609 while (dwarf_siblingof(&child, &child) == 0);
12611 if (!rdr.var_decls_to_re_add_to_tree().empty())
12612 for (list<var_decl_sptr>::const_iterator v =
12613 rdr.var_decls_to_re_add_to_tree().begin();
12614 v != rdr.var_decls_to_re_add_to_tree().end();
12621 string demangled_name =
12623 if (!demangled_name.empty())
12625 std::list<string> fqn_comps;
12627 string mem_name = fqn_comps.back();
12628 fqn_comps.pop_back();
12631 if (!fqn_comps.empty())
12659 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12665 rdr.var_decls_to_re_add_to_tree().clear();
12667 result->set_is_constructed(
true);
12692build_namespace_decl_and_add_to_ir(reader& rdr,
12694 size_t where_offset)
12701 unsigned tag = dwarf_tag(die);
12702 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12709 string name, linkage_name;
12711 die_loc_and_name(rdr, die, loc, name, linkage_name);
12713 result.reset(
new namespace_decl(rdr.env(), name, loc));
12715 rdr.associate_die_to_decl(die, result, where_offset);
12718 if (dwarf_child(die, &child) != 0)
12721 rdr.scope_stack().push(result.get());
12723 build_ir_node_from_die(rdr, &child,
12729 die_is_public_decl(die) && die_is_public_decl(&child),
12731 while (dwarf_siblingof(&child, &child) == 0);
12732 rdr.scope_stack().pop();
12747build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12753 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12755 uint64_t byte_size = 0, bit_size = 0;
12756 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12757 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12760 if (bit_size == 0 && byte_size != 0)
12762 bit_size = byte_size * 8;
12764 string type_name, linkage_name;
12766 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12768 if (byte_size == 0)
12772 if (type_name ==
"void")
12773 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12780 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12782 string normalized_type_name = type_name;
12783 integral_type int_type;
12785 normalized_type_name = int_type.
to_string();
12790 if (corpus_sptr corp = rdr.corpus())
12793 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12794 0, loc, linkage_name));
12795 rdr.associate_die_to_type(die, result, where_offset);
12813build_enum_underlying_type(reader& rdr,
12815 uint64_t enum_size,
12816 bool is_anonymous =
true)
12818 string underlying_type_name =
12822 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12823 enum_size, enum_size, location()));
12824 result->set_is_anonymous(is_anonymous);
12825 result->set_is_artificial(
true);
12828 result = dynamic_pointer_cast<type_decl>(d);
12849build_enum_type(reader& rdr,
12852 size_t where_offset,
12853 bool is_declaration_only)
12859 unsigned tag = dwarf_tag(die);
12860 if (tag != DW_TAG_enumeration_type)
12863 string name, linkage_name;
12865 die_loc_and_name(rdr, die, loc, name, linkage_name);
12867 bool is_anonymous =
false;
12871 name = get_internal_anonymous_die_prefix_name(die);
12874 is_anonymous =
true;
12876 if (
size_t s = scope->get_num_anonymous_member_enums())
12877 name = build_internal_anonymous_die_name(name, s);
12880 bool use_odr = rdr.odr_is_relevant(die);
12892 result = pre_existing_enum;
12894 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12903 if (pre_existing_enum->get_location() == loc)
12904 result = pre_existing_enum;
12909 rdr.associate_die_to_type(die, result, where_offset);
12917 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12919 bool is_artificial = die_is_artificial(die);
12922 bool enum_underlying_type_is_anonymous=
true;
12926 if (dwarf_child(die, &child) == 0)
12930 if (dwarf_tag(&child) != DW_TAG_enumerator)
12935 die_loc_and_name(rdr, &child, l, n, m);
12937 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12938 enms.push_back(enum_type_decl::enumerator(n, val));
12940 while (dwarf_siblingof(&child, &child) == 0);
12948 build_enum_underlying_type(rdr, name, size,
12949 enum_underlying_type_is_anonymous);
12950 t->set_is_declaration_only(is_declaration_only);
12952 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12953 result->set_is_anonymous(is_anonymous);
12954 result->set_is_declaration_only(is_declaration_only);
12955 result->set_is_artificial(is_artificial);
12956 rdr.associate_die_to_type(die, result, where_offset);
12958 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12977finish_member_function_reading(Dwarf_Die* die,
12979 const class_or_union_sptr klass,
12990 size_t is_inline = die_is_declared_inline(die);
12991 bool is_ctor = (f->get_name() == klass->get_name());
12992 bool is_dtor = (!f->get_name().empty()
12993 &&
static_cast<string>(f->get_name())[0] ==
'~');
12994 bool is_virtual = die_is_virtual(die);
12995 int64_t vindex = -1;
12997 die_virtual_function_index(die, vindex);
13000 if (!c->is_struct())
13001 access = private_access;
13002 die_access_specifier(die, access);
13004 m->is_declared_inline(is_inline);
13010 bool is_static = method_t->get_is_for_static_method();
13018 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
13037 Dwarf_Off die_offset = dwarf_dieoffset(die);
13039 rdr.die_function_decl_with_no_symbol_map();
13040 die_function_decl_map_type::const_iterator i =
13041 fns_with_no_symbol.find(die_offset);
13042 if (i == fns_with_no_symbol.end())
13043 fns_with_no_symbol[die_offset] = f;
13064maybe_finish_function_decl_reading(reader& rdr,
13066 size_t where_offset,
13084static type_base_sptr
13085lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
13088 corpus* corp = scope->get_corpus();
13109static type_base_sptr
13110lookup_class_or_typedef_from_corpus(reader& rdr,
13112 bool called_for_public_decl,
13113 size_t where_offset)
13118 string class_name = die_string_attribute(die, DW_AT_name);
13119 if (class_name.empty())
13123 called_for_public_decl,
13126 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
13128 return type_base_sptr();
13139static type_base_sptr
13140lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
13141 const string& type_name)
13144 corpus* corp = scope->get_corpus();
13162static type_base_sptr
13163lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
13164 size_t anonymous_member_type_idx,
13170 string type_name = die_string_attribute(die, DW_AT_name);
13173 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
13175 if (type_name.empty())
13178 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
13196static method_decl_sptr
13197is_function_for_die_a_member_of_class(reader& rdr,
13198 Dwarf_Die* function_die,
13199 const class_or_union_sptr& class_type)
13204 return method_decl_sptr();
13210 method_type = method->get_type();
13215 class_or_union_sptr method_class = method_type->get_class_type();
13218 string method_class_name = method_class->get_qualified_name(),
13219 class_type_name = class_type->get_qualified_name();
13221 if (method_class_name == class_type_name)
13227 return method_decl_sptr();
13249static method_decl_sptr
13250add_or_update_member_function(reader& rdr,
13251 Dwarf_Die* function_die,
13252 const class_or_union_sptr& class_type,
13253 bool called_from_public_decl,
13254 size_t where_offset)
13256 method_decl_sptr method =
13257 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
13260 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
13262 called_from_public_decl,
13265 return method_decl_sptr();
13267 finish_member_function_reading(function_die,
13310add_or_update_class_type(reader& rdr,
13315 bool called_from_public_decl,
13316 size_t where_offset,
13317 bool is_declaration_only)
13323 const die_source source = rdr.get_die_source(die);
13325 unsigned tag = dwarf_tag(die);
13327 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
13331 die_class_or_union_map_type::const_iterator i =
13332 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13333 if (i != rdr.die_wip_classes_map(source).end())
13341 string name, linkage_name;
13343 die_loc_and_name(rdr, die, loc, name, linkage_name);
13345 bool is_anonymous =
false;
13350 name = get_internal_anonymous_die_prefix_name(die);
13353 is_anonymous =
true;
13355 if (
size_t s = scope->get_num_anonymous_member_classes())
13356 name = build_internal_anonymous_die_name(name, s);
13361 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13377 && (result->get_is_declaration_only() == is_declaration_only
13378 || (!result->get_is_declaration_only()
13379 && is_declaration_only)))
13381 rdr.associate_die_to_type(die, result, where_offset);
13400 klass = pre_existing_class;
13403 die_size_in_bits(die, size);
13404 bool is_artificial = die_is_artificial(die);
13407 bool has_child = (dwarf_child(die, &child) == 0);
13409 decl_base_sptr res;
13412 res = result = klass;
13413 if (has_child && klass->get_is_declaration_only()
13414 && klass->get_definition_of_declaration())
13415 res = result =
is_class_type(klass->get_definition_of_declaration());
13417 result->set_location(loc);
13421 result.reset(
new class_decl(rdr.env(), name, size,
13423 decl_base::VISIBILITY_DEFAULT,
13426 result->set_is_declaration_only(is_declaration_only);
13429 result = dynamic_pointer_cast<class_decl>(res);
13433 if (!klass || klass->get_is_declaration_only())
13434 if (size != result->get_size_in_bits())
13435 result->set_size_in_bits(size);
13440 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13453 result->set_is_declaration_only(is_declaration_only);
13457 if (!result->get_is_declaration_only() && has_child)
13458 if (result->get_size_in_bits() == 0 && size != 0)
13459 result->set_size_in_bits(size);
13461 result->set_is_artificial(is_artificial);
13463 rdr.associate_die_to_type(die, result, where_offset);
13465 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13472 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13474 bool is_incomplete_type =
false;
13475 if (is_declaration_only && size == 0 && has_child)
13487 is_incomplete_type =
true;
13490 dynamic_pointer_cast<scope_decl>(res);
13492 rdr.scope_stack().push(scop.get());
13494 if (has_child && !is_incomplete_type)
13496 int anonymous_member_class_index = -1;
13497 int anonymous_member_union_index = -1;
13498 int anonymous_member_enum_index = -1;
13502 tag = dwarf_tag(&child);
13505 if (tag == DW_TAG_inheritance)
13507 result->set_is_declaration_only(
false);
13509 Dwarf_Die type_die;
13510 if (!die_die_attribute(&child, DW_AT_type, type_die))
13513 type_base_sptr base_type;
13515 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13516 called_from_public_decl,
13520 is_type(build_ir_node_from_die(rdr, &type_die,
13521 called_from_public_decl,
13535 die_access_specifier(&child, access);
13537 bool is_virt= die_is_virtual(&child);
13538 int64_t offset = 0;
13539 bool is_offset_present =
13540 die_member_offset(rdr, &child, offset);
13544 is_offset_present ? offset : -1,
13546 if (b->get_is_declaration_only()
13553 && !b->get_qualified_name().empty())
13554 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13555 if (result->find_base_class(b->get_qualified_name()))
13557 result->add_base_specifier(base);
13560 else if (tag == DW_TAG_member
13561 || tag == DW_TAG_variable)
13563 Dwarf_Die type_die;
13564 if (!die_die_attribute(&child, DW_AT_type, type_die))
13569 die_loc_and_name(rdr, &child, loc, n, m);
13574 if (n.substr(0, 5) ==
"_vptr"
13576 && !std::isalnum(n.at(5))
13586 int64_t offset_in_bits = 0;
13587 bool is_laid_out = die_member_offset(rdr, &child,
13592 bool is_static = !is_laid_out;
13594 if (is_static && variable_is_suppressed(rdr,
13597 is_declaration_only))
13600 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13601 called_from_public_decl,
13603 type_base_sptr t =
is_type(ty);
13607 if (n.empty() && !die_is_anonymous_data_member(&child))
13613 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13630 result->set_is_declaration_only(
false);
13636 die_access_specifier(&child, access);
13644 result->add_data_member(dm, access, is_laid_out,
13645 is_static, offset_in_bits);
13647 rdr.associate_die_to_decl(&child, dm, where_offset,
13651 else if (tag == DW_TAG_subprogram)
13654 add_or_update_member_function(rdr, &child, result,
13655 called_from_public_decl,
13658 rdr.associate_die_to_decl(&child, f, where_offset,
13662 else if (die_is_type(&child))
13668 int anonymous_member_type_index = 0;
13672 if (die_is_class_type(&child))
13673 anonymous_member_type_index =
13674 ++anonymous_member_class_index;
13675 else if (dwarf_tag(&child) == DW_TAG_union_type)
13676 anonymous_member_type_index =
13677 ++anonymous_member_union_index;
13678 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13679 anonymous_member_type_index =
13680 ++anonymous_member_enum_index;
13685 && !lookup_class_typedef_or_enum_type_from_corpus
13686 (&child, anonymous_member_type_index, result.get()))
13687 || !result->find_member_type(die_name(&child)))
13688 build_ir_node_from_die(rdr, &child, result.get(),
13689 called_from_public_decl,
13692 }
while (dwarf_siblingof(&child, &child) == 0);
13695 rdr.scope_stack().pop();
13698 die_class_or_union_map_type::const_iterator i =
13699 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13700 if (i != rdr.die_wip_classes_map(source).end())
13705 rdr.die_wip_classes_map(source).erase(i);
13709 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13737static union_decl_sptr
13738add_or_update_union_type(reader& rdr,
13741 union_decl_sptr union_type,
13742 bool called_from_public_decl,
13743 size_t where_offset,
13744 bool is_declaration_only)
13746 union_decl_sptr result;
13750 unsigned tag = dwarf_tag(die);
13752 if (tag != DW_TAG_union_type)
13755 const die_source source = rdr.get_die_source(die);
13757 die_class_or_union_map_type::const_iterator i =
13758 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13759 if (i != rdr.die_wip_classes_map(source).end())
13767 string name, linkage_name;
13769 die_loc_and_name(rdr, die, loc, name, linkage_name);
13771 bool is_anonymous =
false;
13776 name = get_internal_anonymous_die_prefix_name(die);
13779 is_anonymous =
true;
13781 if (
size_t s = scope->get_num_anonymous_member_unions())
13782 name = build_internal_anonymous_die_name(name, s);
13792 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13801 rdr.associate_die_to_type(die, result, where_offset);
13813 if (union_decl_sptr pre_existing_union =
13815 union_type = pre_existing_union;
13818 die_size_in_bits(die, size);
13819 bool is_artificial = die_is_artificial(die);
13823 result = union_type;
13824 result->set_location(loc);
13828 result.reset(
new union_decl(rdr.env(), name, size, loc,
13829 decl_base::VISIBILITY_DEFAULT,
13831 if (is_declaration_only)
13832 result->set_is_declaration_only(
true);
13839 result->set_size_in_bits(size);
13840 result->set_is_declaration_only(
false);
13843 result->set_is_artificial(is_artificial);
13845 rdr.associate_die_to_type(die, result, where_offset);
13847 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13850 bool has_child = (dwarf_child(die, &child) == 0);
13854 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13857 dynamic_pointer_cast<scope_decl>(result);
13859 rdr.scope_stack().push(scop.get());
13865 tag = dwarf_tag(&child);
13867 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13869 Dwarf_Die type_die;
13870 if (!die_die_attribute(&child, DW_AT_type, type_die))
13875 die_loc_and_name(rdr, &child, loc, n, m);
13884 ssize_t offset_in_bits = 0;
13885 decl_base_sptr ty =
13886 is_decl(build_ir_node_from_die(rdr, &type_die,
13887 called_from_public_decl,
13889 type_base_sptr t =
is_type(ty);
13896 result->set_is_declaration_only(
false);
13899 die_access_specifier(&child, access);
13905 if (n.empty() && result->find_data_member(dm))
13911 result->add_data_member(dm, access,
true,
13915 rdr.associate_die_to_decl(&child, dm, where_offset,
13919 else if (tag == DW_TAG_subprogram)
13922 is_decl(build_ir_node_from_die(rdr, &child,
13924 called_from_public_decl,
13932 finish_member_function_reading(&child, f, result, rdr);
13934 rdr.associate_die_to_decl(&child, f, where_offset,
13938 else if (die_is_type(&child))
13939 decl_base_sptr td =
13940 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13941 called_from_public_decl,
13943 }
while (dwarf_siblingof(&child, &child) == 0);
13946 rdr.scope_stack().pop();
13949 die_class_or_union_map_type::const_iterator i =
13950 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13951 if (i != rdr.die_wip_classes_map(source).end())
13956 rdr.die_wip_classes_map(source).erase(i);
13980static type_base_sptr
13981build_qualified_type(reader& rdr,
13983 bool called_from_public_decl,
13984 size_t where_offset)
13986 type_base_sptr result;
13990 unsigned tag = dwarf_tag(die);
13992 if (tag != DW_TAG_const_type
13993 && tag != DW_TAG_volatile_type
13994 && tag != DW_TAG_restrict_type)
13997 Dwarf_Die underlying_type_die;
13998 decl_base_sptr utype_decl;
13999 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14003 utype_decl = build_ir_node_for_void_type(rdr);
14006 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
14007 called_from_public_decl,
14014 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14017 rdr.associate_die_to_type(die, result, where_offset);
14021 type_base_sptr utype =
is_type(utype_decl);
14025 if (tag == DW_TAG_const_type)
14026 qual |= qualified_type_def::CV_CONST;
14027 else if (tag == DW_TAG_volatile_type)
14028 qual |= qualified_type_def::CV_VOLATILE;
14029 else if (tag == DW_TAG_restrict_type)
14030 qual |= qualified_type_def::CV_RESTRICT;
14035 result.reset(
new qualified_type_def(utype, qual, location()));
14037 rdr.associate_die_to_type(die, result, where_offset);
14055schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
14060 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
14062 rdr.schedule_type_for_late_canonicalization(t);
14066 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
14068 rdr.schedule_type_for_late_canonicalization(t);
14072 for (vector<array_type_def::subrange_sptr>::const_iterator i =
14073 type->get_subranges().begin();
14074 i != type->get_subranges().end();
14077 if (!(*i)->get_scope())
14079 rdr.schedule_type_for_late_canonicalization(*i);
14082 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
14084 rdr.schedule_type_for_late_canonicalization(type);
14103static decl_base_sptr
14104maybe_strip_qualification(
const qualified_type_def_sptr t,
14110 decl_base_sptr result = t;
14111 type_base_sptr u = t->get_underlying_type();
14115 if (result.get() != t.get())
14121 scope_decl * scope = 0;
14124 scope = array->get_scope();
14127 schedule_array_tree_for_late_canonicalization(array, rdr);
14129 t->set_underlying_type(array);
14130 u = t->get_underlying_type();
14138 schedule_array_tree_for_late_canonicalization(typdef, rdr);
14141 t->set_underlying_type(typdef);
14142 u = t->get_underlying_type();
14151 type_base_sptr element_type = array->get_element_type();
14156 ABG_ASSERT(!qualified->get_canonical_type());
14158 quals |= t->get_cv_quals();
14159 qualified->set_cv_quals(quals);
14165 qualified_type_def_sptr qual_type
14166 (
new qualified_type_def(element_type,
14168 t->get_location()));
14171 array->set_element_type(qual_type);
14172 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
14197build_pointer_type_def(reader& rdr,
14199 bool called_from_public_decl,
14200 size_t where_offset)
14207 unsigned tag = dwarf_tag(die);
14208 if (tag != DW_TAG_pointer_type)
14212 Dwarf_Die underlying_type_die;
14213 bool has_underlying_type_die =
false;
14214 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14217 utype_decl = build_ir_node_for_void_type(rdr);
14219 has_underlying_type_die =
true;
14221 if (!utype_decl && has_underlying_type_die)
14222 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
14223 called_from_public_decl,
14230 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14237 type_base_sptr utype =
is_type(utype_decl);
14243 uint64_t size = rdr.cur_transl_unit()->get_address_size();
14244 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14251 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
14253 result.reset(
new pointer_type_def(utype, size, 0, location()));
14259 rdr.associate_die_to_type(die, result, where_offset);
14281build_reference_type(reader& rdr,
14283 bool called_from_public_decl,
14284 size_t where_offset)
14291 unsigned tag = dwarf_tag(die);
14292 if (tag != DW_TAG_reference_type
14293 && tag != DW_TAG_rvalue_reference_type)
14296 Dwarf_Die underlying_type_die;
14297 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14301 build_ir_node_from_die(rdr, &underlying_type_die,
14302 called_from_public_decl,
14309 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14316 type_base_sptr utype =
is_type(utype_decl);
14322 uint64_t size = rdr.cur_transl_unit()->get_address_size();
14323 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14328 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
14330 bool is_lvalue = tag == DW_TAG_reference_type;
14332 result.reset(
new reference_type_def(utype, is_lvalue, size,
14335 if (corpus_sptr corp = rdr.corpus())
14338 rdr.associate_die_to_type(die, result, where_offset);
14361build_ptr_to_mbr_type(reader& rdr,
14363 bool called_from_public_decl,
14364 size_t where_offset)
14371 unsigned tag = dwarf_tag(die);
14372 if (tag != DW_TAG_ptr_to_member_type)
14375 Dwarf_Die data_member_type_die, containing_type_die;
14377 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
14378 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
14382 build_ir_node_from_die(rdr, &data_member_type_die,
14383 called_from_public_decl, where_offset);
14384 if (!data_member_type)
14388 build_ir_node_from_die(rdr, &containing_type_die,
14389 called_from_public_decl, where_offset);
14390 if (!containing_type)
14397 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14404 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
14406 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
14413 rdr.associate_die_to_type(die, result, where_offset);
14434build_function_type(reader& rdr,
14436 class_or_union_sptr is_method,
14437 size_t where_offset)
14444 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14445 || dwarf_tag(die) == DW_TAG_subprogram);
14447 const die_source source = rdr.get_die_source(die);
14450 size_t off = dwarf_dieoffset(die);
14451 auto i = rdr.die_wip_function_types_map(source).find(off);
14452 if (i != rdr.die_wip_function_types_map(source).end())
14460 decl_base_sptr type_decl;
14468 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14472 rdr.associate_die_to_type(die, result, where_offset);
14489 rdr.associate_die_to_type(die, fn_type, where_offset);
14497 bool is_const =
false;
14498 bool is_static =
false;
14499 Dwarf_Die object_pointer_die;
14500 Dwarf_Die class_type_die;
14501 bool has_this_parm_die =
14502 die_function_type_is_method_type(rdr, die, where_offset,
14503 object_pointer_die,
14506 if (has_this_parm_die)
14511 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14519 class_or_union_sptr klass_type =
14524 is_method = klass_type;
14533 result.reset(is_method
14534 ?
new method_type(is_method, is_const,
14535 tu->get_address_size(),
14537 :
new function_type(rdr.env(), tu->get_address_size(),
14539 rdr.associate_die_to_type(die, result, where_offset);
14540 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14542 type_base_sptr return_type;
14543 Dwarf_Die ret_type_die;
14544 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14546 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14550 return_type =
is_type(build_ir_node_for_void_type(rdr));
14551 result->set_return_type(return_type);
14556 if (dwarf_child(die, &child) == 0)
14559 int child_tag = dwarf_tag(&child);
14560 if (child_tag == DW_TAG_formal_parameter)
14563 string name, linkage_name;
14565 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14570 bool is_artificial = die_is_artificial(&child);
14571 type_base_sptr parm_type;
14572 Dwarf_Die parm_type_die;
14573 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14575 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14582 && function_parms.empty())
14598 (
new function_decl::parameter(parm_type, name, loc,
14601 function_parms.push_back(p);
14603 else if (child_tag == DW_TAG_unspecified_parameters)
14606 bool is_artificial = die_is_artificial(&child);
14608 type_base_sptr parm_type =
14609 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14611 (
new function_decl::parameter(parm_type,
14616 function_parms.push_back(p);
14626 while (dwarf_siblingof(&child, &child) == 0);
14628 result->set_parameters(function_parms);
14630 tu->bind_function_type_life_time(result);
14632 result->set_is_artificial(
true);
14634 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14637 die_function_type_map_type::const_iterator i =
14638 rdr.die_wip_function_types_map(source).
14639 find(dwarf_dieoffset(die));
14640 if (i != rdr.die_wip_function_types_map(source).end())
14641 rdr.die_wip_function_types_map(source).erase(i);
14644 maybe_canonicalize_type(result, rdr);
14671build_subrange_type(reader& rdr,
14672 const Dwarf_Die* die,
14673 size_t where_offset,
14674 bool associate_type_to_die)
14681 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
14682 if (tag != DW_TAG_subrange_type)
14685 string name = die_name(die);
14688 Dwarf_Die underlying_type_die;
14689 type_base_sptr underlying_type;
14691 bool is_signed =
false;
14692 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14694 is_type(build_ir_node_from_die(rdr,
14695 &underlying_type_die,
14699 if (underlying_type)
14702 if (die_unsigned_constant_attribute (&underlying_type_die,
14705 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14711 bool has_size_info =
false;
14713 if ((has_size_info = die_unsigned_constant_attribute(die,
14714 DW_AT_byte_size, size)))
14717 has_size_info = die_unsigned_constant_attribute(die,
14718 DW_AT_bit_size, size);
14721 array_type_def::subrange_type::bound_value lower_bound =
14722 get_default_array_lower_bound(language);
14723 array_type_def::subrange_type::bound_value upper_bound;
14724 uint64_t count = 0;
14725 bool is_non_finite =
false;
14726 bool non_zero_count_present =
false;
14737 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14739 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14740 is_signed, upper_bound);
14741 if (!found_upper_bound)
14742 found_upper_bound = subrange_die_indirect_bound_value(die,
14747 if (!found_upper_bound)
14760 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14768 non_zero_count_present =
true;
14773 int64_t u = lower_bound.get_signed_value() + count;
14775 upper_bound = u - 1;
14778 if (!non_zero_count_present)
14782 is_non_finite =
true;
14785 if (UINT64_MAX == upper_bound.get_unsigned_value())
14788 is_non_finite =
true;
14791 (
new array_type_def::subrange_type(rdr.env(),
14797 result->is_non_finite(is_non_finite);
14800 result->set_size_in_bits(size);
14807 if (!underlying_type)
14808 result->set_size_in_bits(rdr.cur_transl_unit()->get_address_size());
14813 || (result->get_length() ==
14814 (uint64_t) (result->get_upper_bound()
14815 - result->get_lower_bound() + 1)));
14817 if (associate_type_to_die)
14818 rdr.associate_die_to_type(die, result, where_offset);
14840build_subranges_from_array_type_die(reader& rdr,
14841 const Dwarf_Die* die,
14843 size_t where_offset,
14844 bool associate_type_to_die)
14848 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
14852 int child_tag = dwarf_tag(&child);
14853 if (child_tag == DW_TAG_subrange_type)
14856 if (associate_type_to_die)
14862 build_ir_node_from_die(rdr, &child,
14871 s = build_subrange_type(rdr, &child,
14875 subranges.push_back(s);
14878 while (dwarf_siblingof(&child, &child) == 0);
14899build_array_type(reader& rdr,
14901 bool called_from_public_decl,
14902 size_t where_offset)
14909 unsigned tag = dwarf_tag(die);
14910 if (tag != DW_TAG_array_type)
14913 decl_base_sptr type_decl;
14914 Dwarf_Die type_die;
14916 if (die_die_attribute(die, DW_AT_type, type_die))
14917 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14918 called_from_public_decl,
14925 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14932 type_base_sptr type =
is_type(type_decl);
14937 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14939 result.reset(
new array_type_def(type, subranges, location()));
14961build_typedef_type(reader& rdr,
14963 bool called_from_public_decl,
14964 size_t where_offset)
14971 unsigned tag = dwarf_tag(die);
14972 if (tag != DW_TAG_typedef)
14975 string name, linkage_name;
14977 die_loc_and_name(rdr, die, loc, name, linkage_name);
14979 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14985 type_base_sptr utype;
14986 Dwarf_Die underlying_type_die;
14987 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14990 utype = rdr.env().get_void_type();
14994 is_type(build_ir_node_from_die(rdr,
14995 &underlying_type_die,
14996 called_from_public_decl,
15002 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
15009 decl_base_sptr decl =
is_decl(utype);
15011 decl->set_naming_typedef(result);
15013 rdr.maybe_schedule_declaration_only_class_for_resolution
15016 rdr.maybe_schedule_declaration_only_enum_for_resolution
15021 rdr.associate_die_to_type(die, result, where_offset);
15058build_or_get_var_decl_if_not_suppressed(reader& rdr,
15061 size_t where_offset,
15062 bool is_declaration_only,
15064 bool is_required_decl_spec)
15067 if (variable_is_suppressed(rdr, scope, die,
15068 is_declaration_only,
15069 is_required_decl_spec))
15074 string var_name = die_name(die);
15075 if (!var_name.empty())
15076 if ((var = class_type->find_data_member(var_name)))
15079 var = build_var_decl(rdr, die, where_offset, result);
15102build_var_decl(reader& rdr,
15104 size_t where_offset,
15110 int tag = dwarf_tag(die);
15111 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
15113 if (!die_is_public_decl(die))
15116 type_base_sptr type;
15117 Dwarf_Die type_die;
15118 if (die_die_attribute(die, DW_AT_type, type_die))
15120 decl_base_sptr ty =
15121 is_decl(build_ir_node_from_die(rdr, &type_die,
15130 if (!type && !result)
15133 string name, linkage_name;
15135 die_loc_and_name(rdr, die, loc, name, linkage_name);
15138 result.reset(
new var_decl(name, type, loc, linkage_name));
15144 if (!linkage_name.empty())
15145 result->set_linkage_name(linkage_name);
15148 result->set_type(type);
15154 if (!result->get_symbol())
15157 Dwarf_Addr var_addr;
15159 if (rdr.get_variable_address(die, var_addr))
15162 update_main_symbol(var_addr,
15163 result->get_linkage_name().empty()
15164 ? result->get_name()
15165 : result->get_linkage_name());
15166 var_sym = rdr.variable_symbol_is_exported(var_addr);
15171 result->set_symbol(var_sym);
15174 string linkage_name = result->get_linkage_name();
15175 if (linkage_name.empty()
15176 || !var_sym->get_alias_from_name(linkage_name))
15177 result->set_linkage_name(var_sym->get_name());
15178 result->set_is_in_public_symbol_table(
true);
15181 if (!var_sym && rdr.is_decl_die_with_undefined_symbol(die))
15185 string n = result->get_linkage_name();
15187 n = result->get_name();
15188 var_sym = rdr.symtab()->lookup_undefined_variable_symbol(n);
15191 result->set_symbol(var_sym);
15192 result->set_is_in_public_symbol_table(
false);
15219function_is_suppressed(
const reader& rdr,
15220 const scope_decl* scope,
15221 Dwarf_Die *function_die,
15222 bool is_declaration_only)
15224 if (function_die == 0
15225 || dwarf_tag(function_die) != DW_TAG_subprogram)
15228 string fname = die_string_attribute(function_die, DW_AT_name);
15229 string flinkage_name = die_linkage_name(function_die);
15230 if (flinkage_name.empty() && die_is_in_c(function_die))
15231 flinkage_name = fname;
15241 && (!is_declaration_only || rdr.drop_undefined_syms()))
15243 Dwarf_Addr fn_addr;
15244 if (!rdr.get_function_address(function_die, fn_addr))
15248 rdr.function_symbol_is_exported(fn_addr);
15251 if (!symbol->is_suppressed())
15258 if (symbol->has_aliases())
15260 !a->is_main_symbol(); a = a->get_next_alias())
15261 if (!a->is_suppressed())
15310build_or_get_fn_decl_if_not_suppressed(reader& rdr,
15313 size_t where_offset,
15314 bool is_declaration_only,
15318 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
15321 string name = die_name(fn_die);
15322 string linkage_name = die_linkage_name(fn_die);
15323 bool is_dtor = !name.empty() && name[0]==
'~';
15324 bool is_virtual =
false;
15327 Dwarf_Attribute attr;
15328 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
15329 DW_AT_vtable_elem_location,
15341 if (!result && (!(is_dtor && is_virtual)))
15344 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
15345 rdr.associate_die_to_decl(fn_die, fn,
true);
15346 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
15354 string linkage_name = die_linkage_name(fn_die);
15355 fn = klass->find_member_function_sptr(linkage_name);
15362 if (!fn || !fn->get_symbol())
15369 fn = build_function_decl(rdr, fn_die, where_offset, result);
15394variable_is_suppressed(
const reader& rdr,
15395 const scope_decl* scope,
15396 Dwarf_Die *variable_die,
15397 bool is_declaration_only,
15398 bool is_required_decl_spec)
15400 if (variable_die == 0
15401 || (dwarf_tag(variable_die) != DW_TAG_variable
15402 && dwarf_tag(variable_die) != DW_TAG_member))
15405 string name = die_string_attribute(variable_die, DW_AT_name);
15406 string linkage_name = die_linkage_name(variable_die);
15407 if (linkage_name.empty() && die_is_in_c(variable_die))
15408 linkage_name = name;
15417 && !is_required_decl_spec
15421 && (!is_declaration_only || !rdr.load_undefined_interfaces()))
15423 Dwarf_Addr var_addr = 0;
15424 if (!rdr.get_variable_address(variable_die, var_addr))
15428 rdr.variable_symbol_is_exported(var_addr);
15431 if (!symbol->is_suppressed())
15438 if (symbol->has_aliases())
15440 !a->is_main_symbol(); a = a->get_next_alias())
15441 if (!a->is_suppressed())
15470type_is_suppressed(
const reader& rdr,
15471 const scope_decl* scope,
15472 Dwarf_Die *type_die,
15473 bool &type_is_opaque)
15476 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
15477 && dwarf_tag(type_die) != DW_TAG_class_type
15478 && dwarf_tag(type_die) != DW_TAG_structure_type
15479 && dwarf_tag(type_die) != DW_TAG_union_type))
15482 string type_name, linkage_name;
15483 location type_location;
15484 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15508type_is_suppressed(
const reader& rdr,
15509 const scope_decl* scope,
15510 Dwarf_Die *type_die)
15512 bool type_is_opaque =
false;
15513 return type_is_suppressed(rdr, scope, type_die, type_is_opaque);
15537get_opaque_version_of_type(reader &rdr,
15539 Dwarf_Die *type_die,
15540 size_t where_offset)
15547 unsigned tag = dwarf_tag(type_die);
15548 if (tag != DW_TAG_class_type
15549 && tag != DW_TAG_structure_type
15550 && tag != DW_TAG_union_type
15551 && tag != DW_TAG_enumeration_type)
15554 string type_name, linkage_name;
15555 location type_location;
15556 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15565 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15567 string_classes_or_unions_map::const_iterator i =
15568 rdr.declaration_only_classes().find(qualified_name);
15569 if (i != rdr.declaration_only_classes().end())
15570 result = i->second.back();
15581 tag == DW_TAG_structure_type,
15583 decl_base::VISIBILITY_DEFAULT));
15584 klass->set_is_declaration_only(
true);
15585 klass->set_is_artificial(die_is_artificial(type_die));
15587 rdr.associate_die_to_type(type_die, klass, where_offset);
15588 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15593 if (tag == DW_TAG_enumeration_type)
15595 string_enums_map::const_iterator i =
15596 rdr.declaration_only_enums().find(qualified_name);
15597 if (i != rdr.declaration_only_enums().end())
15598 result = i->second.back();
15603 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15606 build_enum_underlying_type(rdr, type_name, size,
15614 enum_type->set_is_artificial(die_is_artificial(type_die));
15616 result = enum_type;
15639 elf_symbol::FUNC_TYPE,
15640 elf_symbol::GLOBAL_BINDING,
15644 elf_symbol::DEFAULT_VISIBILITY);
15662build_function_decl(reader& rdr,
15664 size_t where_offset,
15670 int tag = dwarf_tag(die);
15671 ABG_ASSERT(tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine);
15673 if (!die_is_public_decl(die))
15679 string fname, flinkage_name;
15681 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15683 size_t is_inline = die_is_declared_inline(die);
15684 class_or_union_sptr is_method =
15697 if (!flinkage_name.empty()
15698 && result->get_linkage_name() != flinkage_name)
15699 result->set_linkage_name(flinkage_name);
15701 if (!result->get_location())
15702 result->set_location(floc);
15703 result->is_declared_inline(is_inline);
15712 maybe_canonicalize_type(fn_type, rdr);
15714 result.reset(is_method
15715 ?
new method_decl(fname, fn_type,
15718 :
new function_decl(fname, fn_type,
15725 if (!result->get_symbol())
15728 Dwarf_Addr fn_addr;
15729 if (rdr.get_function_address(die, fn_addr))
15732 update_main_symbol(fn_addr,
15733 result->get_linkage_name().empty()
15734 ? result->get_name()
15735 : result->get_linkage_name());
15736 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15739 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15741 result->set_symbol(fn_sym);
15742 string linkage_name = result->get_linkage_name();
15743 if (linkage_name.empty())
15744 result->set_linkage_name(fn_sym->get_name());
15745 result->set_is_in_public_symbol_table(
true);
15748 if (!fn_sym && rdr.is_decl_die_with_undefined_symbol(die))
15752 string n = result->get_linkage_name();
15754 n = result->get_name();
15755 fn_sym = rdr.symtab()->lookup_undefined_function_symbol(n);
15758 result->set_symbol(fn_sym);
15759 result->set_is_in_public_symbol_table(
false);
15764 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15766 size_t die_offset = dwarf_dieoffset(die);
15771 && !result->get_linkage_name().empty())
15777 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15796maybe_canonicalize_type(
const type_base_sptr& t,
15809 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15819 rdr.schedule_type_for_late_canonicalization(t);
15821 rdr.schedule_type_for_late_canonicalization(t);
15832maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15835 if (
is_type(member_type_declaration)
15838 class_or_union* scope =
15844 if (!cl->is_struct())
15845 access = private_access;
15847 die_access_specifier(die, access);
15867 const Dwarf_Die *fn_die)
15869 if (!fn || fn->get_scope())
15873 !die_is_virtual(fn_die)
15875 && !fn->get_symbol())
15920build_ir_node_from_die(reader& rdr,
15923 bool called_from_public_decl,
15924 size_t where_offset,
15925 bool is_declaration_only,
15926 bool is_required_decl_spec)
15930 if (!die || !scope)
15933 int tag = dwarf_tag(die);
15935 if (!called_from_public_decl)
15937 if (rdr.load_all_types() && die_is_type(die))
15941 else if (tag != DW_TAG_subprogram
15942 && tag != DW_TAG_variable
15943 && tag != DW_TAG_member
15944 && tag != DW_TAG_namespace)
15948 const die_source source_of_die = rdr.get_die_source(die);
15950 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15953 if (rdr.load_all_types())
15954 if (called_from_public_decl)
15955 if (type_base_sptr t =
is_type(result))
15956 if (corpus *abi_corpus = scope->get_corpus())
15957 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15966 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15971 case DW_TAG_base_type:
15980 case DW_TAG_typedef:
15983 called_from_public_decl,
15989 maybe_set_member_type_access_specifier(
is_decl(result), die);
15990 maybe_canonicalize_type(t, rdr);
15995 case DW_TAG_pointer_type:
15998 build_pointer_type_def(rdr, die,
15999 called_from_public_decl,
16006 maybe_canonicalize_type(p, rdr);
16011 case DW_TAG_reference_type:
16012 case DW_TAG_rvalue_reference_type:
16015 build_reference_type(rdr, die,
16016 called_from_public_decl,
16023 rdr.associate_die_to_type(die, r, where_offset);
16024 maybe_canonicalize_type(r, rdr);
16029 case DW_TAG_ptr_to_member_type:
16032 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
16038 maybe_canonicalize_type(p, rdr);
16043 case DW_TAG_const_type:
16044 case DW_TAG_volatile_type:
16045 case DW_TAG_restrict_type:
16048 build_qualified_type(rdr, die,
16049 called_from_public_decl,
16060 type_base_sptr ty =
is_type(d);
16064 rdr.associate_die_to_type(die, ty, where_offset);
16067 maybe_canonicalize_type(
is_type(result), rdr);
16072 case DW_TAG_enumeration_type:
16074 bool type_is_opaque =
false;
16075 bool type_suppressed =
16076 type_is_suppressed(rdr, scope, die, type_is_opaque);
16077 if (type_suppressed && type_is_opaque)
16085 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
16086 maybe_canonicalize_type(
is_type(result), rdr);
16088 else if (!type_suppressed)
16092 is_declaration_only);
16096 maybe_set_member_type_access_specifier(
is_decl(result), die);
16097 maybe_canonicalize_type(
is_type(result), rdr);
16103 case DW_TAG_class_type:
16104 case DW_TAG_structure_type:
16106 bool type_is_opaque =
false;
16107 bool type_suppressed=
16108 type_is_suppressed(rdr, scope, die, type_is_opaque);
16110 if (type_suppressed && type_is_opaque)
16118 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
16119 maybe_canonicalize_type(
is_type(result), rdr);
16121 else if (!type_suppressed)
16123 Dwarf_Die spec_die;
16126 if (die_die_attribute(die, DW_AT_specification, spec_die))
16129 get_scope_for_die(rdr, &spec_die,
16130 called_from_public_decl,
16133 decl_base_sptr cl =
16134 is_decl(build_ir_node_from_die(rdr, &spec_die,
16136 called_from_public_decl,
16138 is_declaration_only,
16141 klass = dynamic_pointer_cast<class_decl>(cl);
16145 add_or_update_class_type(rdr, die,
16147 tag == DW_TAG_structure_type,
16149 called_from_public_decl,
16151 is_declaration_only);
16155 add_or_update_class_type(rdr, die, scope,
16156 tag == DW_TAG_structure_type,
16158 called_from_public_decl,
16160 is_declaration_only);
16164 maybe_set_member_type_access_specifier(klass, die);
16165 maybe_canonicalize_type(klass, rdr);
16170 case DW_TAG_union_type:
16171 if (!type_is_suppressed(rdr, scope, die))
16173 union_decl_sptr union_type =
16174 add_or_update_union_type(rdr, die, scope,
16176 called_from_public_decl,
16178 is_declaration_only);
16181 maybe_set_member_type_access_specifier(union_type, die);
16182 maybe_canonicalize_type(union_type, rdr);
16184 result = union_type;
16187 case DW_TAG_string_type:
16189 case DW_TAG_subroutine_type:
16197 result->set_is_artificial(
false);
16198 maybe_canonicalize_type(f, rdr);
16202 case DW_TAG_array_type:
16206 called_from_public_decl,
16212 rdr.associate_die_to_type(die, a, where_offset);
16213 maybe_canonicalize_type(a, rdr);
16217 case DW_TAG_subrange_type:
16223 build_subrange_type(rdr, die, where_offset);
16228 rdr.associate_die_to_type(die, s, where_offset);
16229 maybe_canonicalize_type(s, rdr);
16233 case DW_TAG_packed_type:
16235 case DW_TAG_set_type:
16237 case DW_TAG_file_type:
16239 case DW_TAG_thrown_type:
16241 case DW_TAG_interface_type:
16243 case DW_TAG_unspecified_type:
16245 case DW_TAG_shared_type:
16248 case DW_TAG_compile_unit:
16253 case DW_TAG_namespace:
16254 case DW_TAG_module:
16255 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
16258 case DW_TAG_variable:
16259 case DW_TAG_member:
16261 Dwarf_Die spec_die;
16262 bool var_is_cloned =
false;
16264 if (tag == DW_TAG_member)
16267 if (die_die_attribute(die, DW_AT_specification, spec_die,
false)
16268 || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
16272 get_scope_for_die(rdr, &spec_die,
16274 die_is_effectively_public_decl(rdr, die),
16279 is_decl(build_ir_node_from_die(rdr, &spec_die,
16281 called_from_public_decl,
16283 is_declaration_only,
16288 dynamic_pointer_cast<var_decl>(d);
16291 m = build_var_decl(rdr, die, where_offset, m);
16295 rdr.associate_die_to_decl(die, m, where_offset,
16301 rdr.var_decls_to_re_add_to_tree().push_back(m);
16304 rdr.add_var_to_exported_or_undefined_decls(m.get());
16310 build_or_get_var_decl_if_not_suppressed(rdr, scope, die,
16312 is_declaration_only,
16314 is_required_decl_spec))
16318 v = dynamic_pointer_cast<var_decl>(result);
16321 rdr.var_decls_to_re_add_to_tree().push_back(v);
16322 rdr.add_var_to_exported_or_undefined_decls(v.get());
16327 case DW_TAG_subprogram:
16328 case DW_TAG_inlined_subroutine:
16330 if (die_is_artificial(die))
16333 Dwarf_Die abstract_origin_die;
16334 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
16335 abstract_origin_die,
16339 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
16341 scope_decl* interface_scope = scope ? scope : s.get();
16344 string linkage_name = die_linkage_name(die);
16345 string spec_linkage_name;
16352 if (!linkage_name.empty())
16355 class_scope->find_member_function_sptr(linkage_name)))
16360 spec_linkage_name = existing_fn->get_linkage_name();
16361 if (has_abstract_origin
16362 && !spec_linkage_name.empty()
16363 && linkage_name != spec_linkage_name)
16370 existing_fn = existing_fn->clone();
16376 rdr.scope_stack().push(interface_scope);
16383 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
16385 is_declaration_only,
16388 if (result && !existing_fn)
16394 && !is_required_decl_spec)
16410 sptr_utils::noop_deleter());
16412 finish_member_function_reading(die, fn, klass, rdr);
16423 rdr.add_fn_to_exported_or_undefined_decls(fn.get());
16424 rdr.associate_die_to_decl(die, fn, where_offset,
16426 maybe_canonicalize_type(fn->get_type(), rdr);
16429 rdr.scope_stack().pop();
16433 case DW_TAG_formal_parameter:
16438 case DW_TAG_constant:
16440 case DW_TAG_enumerator:
16443 case DW_TAG_partial_unit:
16444 case DW_TAG_imported_unit:
16451 case DW_TAG_dwarf_procedure:
16452 case DW_TAG_imported_declaration:
16453 case DW_TAG_entry_point:
16455 case DW_TAG_lexical_block:
16456 case DW_TAG_unspecified_parameters:
16457 case DW_TAG_variant:
16458 case DW_TAG_common_block:
16459 case DW_TAG_common_inclusion:
16460 case DW_TAG_inheritance:
16461 case DW_TAG_with_stmt:
16462 case DW_TAG_access_declaration:
16463 case DW_TAG_catch_block:
16464 case DW_TAG_friend:
16465 case DW_TAG_namelist:
16466 case DW_TAG_namelist_item:
16467 case DW_TAG_template_type_parameter:
16468 case DW_TAG_template_value_parameter:
16469 case DW_TAG_try_block:
16470 case DW_TAG_variant_part:
16471 case DW_TAG_imported_module:
16472 case DW_TAG_condition:
16473 case DW_TAG_type_unit:
16474 case DW_TAG_template_alias:
16475 case DW_TAG_lo_user:
16476 case DW_TAG_MIPS_loop:
16477 case DW_TAG_format_label:
16478 case DW_TAG_function_template:
16479 case DW_TAG_class_template:
16480 case DW_TAG_GNU_BINCL:
16481 case DW_TAG_GNU_EINCL:
16482 case DW_TAG_GNU_template_template_param:
16483 case DW_TAG_GNU_template_parameter_pack:
16484 case DW_TAG_GNU_formal_parameter_pack:
16485 case DW_TAG_GNU_call_site:
16486 case DW_TAG_GNU_call_site_parameter:
16487 case DW_TAG_hi_user:
16492 if (result && tag != DW_TAG_subroutine_type)
16493 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
16497 if (rdr.load_all_types())
16498 if (called_from_public_decl)
16499 if (type_base_sptr t =
is_type(result))
16500 if (corpus *abi_corpus = scope->get_corpus())
16501 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
16511static decl_base_sptr
16512build_ir_node_for_void_type(reader& rdr)
16514 const environment& env = rdr.env();
16516 type_base_sptr t = env.get_void_type();
16520 return type_declaration;
16535build_ir_node_for_void_pointer_type(reader& rdr)
16537 const environment& env = rdr.env();
16539 type_base_sptr t = env.get_void_pointer_type();
16543 return type_declaration;
16551static decl_base_sptr
16552build_ir_node_for_variadic_parameter_type(reader &rdr)
16555 const environment& env = rdr.env();
16557 type_base_sptr t = env.get_variadic_parameter_type();
16561 return type_declaration;
16587build_ir_node_from_die(reader& rdr,
16589 bool called_from_public_decl,
16590 size_t where_offset)
16593 return decl_base_sptr();
16603 bool consider_as_called_from_public_decl =
16604 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
16606 consider_as_called_from_public_decl,
16608 return build_ir_node_from_die(rdr, die, scope.get(),
16609 called_from_public_decl,
16610 where_offset,
true);
16644elf_based_reader_sptr
16646 const vector<char**>& debug_info_root_paths,
16648 bool load_all_types,
16649 bool linux_kernel_mode)
16652 reader_sptr r = reader::create(elf_path,
16653 debug_info_root_paths,
16656 linux_kernel_mode);
16657 return static_pointer_cast<elf_based_reader>(r);
16696 const std::string& elf_path,
16697 const vector<char**>&debug_info_root_path,
16698 bool read_all_types,
16699 bool linux_kernel_mode)
16701 reader& r =
dynamic_cast<reader&
>(rdr);
16702 r.initialize(elf_path, debug_info_root_path,
16703 read_all_types, linux_kernel_mode);
16740 const vector<char**>& debug_info_root_paths,
16742 bool load_all_types,
16745 elf_based_reader_sptr rdr =
16746 dwarf::reader::create(elf_path, debug_info_root_paths,
16750 return rdr->read_corpus(status);
16771 const string& elf_path,
16772 const string& symbol_name,
16774 vector<elf_symbol_sptr>& syms)
16777 if (elf_version(EV_CURRENT) == EV_NONE)
16780 int fd = open(elf_path.c_str(), O_RDONLY);
16788 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
16816 const string& path,
16817 const string& symname,
16818 vector<elf_symbol_sptr>& syms)
16820 if (elf_version(EV_CURRENT) == EV_NONE)
16823 int fd = open(path.c_str(), O_RDONLY);
16831 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one.
bool architecture_is_big_endian(Elf *elf_handle)
Test if the endianness of the current binary is Big Endian.
bool get_binary_load_address(Elf *elf_handle, GElf_Addr &load_address)
Get the address at which a given binary is loaded in memory.
bool get_version_for_symbol(Elf *elf_handle, size_t symbol_index, bool get_def_version, elf_symbol::version &version)
Return the version for a symbol that is at a given index in its SHT_SYMTAB section.
elf_symbol::binding stb_to_elf_symbol_binding(unsigned char stb)
Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND macros) into an elf_symbol::binding va...
elf_symbol::visibility stv_to_elf_symbol_visibility(unsigned char stv)
Convert an ELF symbol visiblity given by the symbols ->st_other data member as returned by the GELF_S...
bool find_symbol_table_section_index(Elf *elf_handle, size_t &symtab_index)
Find the index (in the section headers table) of the symbol table section.
elf_symbol::type stt_to_elf_symbol_type(unsigned char stt)
Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE macros) into an elf_symbol::type value.
hash_table_kind find_hash_table_section_index(Elf *elf_handle, size_t &ht_section_index, size_t &symtab_section_index)
Get the offset offset of the hash table section.
This contains a set of ELF utilities used by the dwarf reader.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
elf_symbol_sptr function_symbol_is_undefined(const string &name) const
Test if a name is the name of an undefined function symbol.
const string & elf_architecture() const
Get the value of the 'ARCHITECTURE' property of the current ELF file.
const Dwarf * dwarf_debug_info() const
Getter of the handle used to access DWARF information from the current ELF file.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
const Dwarf * alternate_dwarf_debug_info() const
Getter of the handle use to access DWARF information from the alternate split DWARF information.
bool refers_to_alt_debug_info(string &alt_di_path) const
Check if the underlying elf file refers to an alternate debug info file associated to it.
elf_symbol_sptr variable_symbol_is_undefined(const string &name) const
Test if a name is the name of an undefined variable symbol.
elf_symbol_sptr variable_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given variable symbol has been exported.
elf_symbol_sptr function_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given function symbol has been exported.
const vector< string > & dt_needed() const
Get the value of the DT_NEEDED property of the current ELF file.
The common interface of readers based on ELF.
elf_based_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &env)
Readers that implement this interface must provide a factory method to create a reader instance as th...
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
status
The status of the fe_iface::read_corpus call.
@ STATUS_DEBUG_INFO_NOT_FOUND
This status is for when the debug info could not be read.
@ STATUS_ALT_DEBUG_INFO_NOT_FOUND
This status is for when the alternate debug info could not be found.
@ STATUS_UNKNOWN
The status is in an unknown state.
const options_type & options() const
Getter of the the options of the current Front End Interface.
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
scope_decl * get_scope() const
Return the type containing the current decl, if any.
The abstraction of the version of an ELF symbol.
binding
The binding of a symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
The internal representation of an integral type.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
The source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
language
The language of the translation unit.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
unordered_map< std::pair< offset_type, offset_type >, offset_pair_set_type, offset_pair_hash > offset_pair_set_map_type
A convenience typedef for an unordered_map that associates a pair of offset_type to a set of pairs of...
unordered_map< Dwarf_Off, translation_unit_sptr > die_tu_map_type
Convenience typedef for a map which key is the offset of a DW_TAG_compile_unit and the value is the c...
bool lookup_symbol_from_elf(const environment &env, const string &elf_path, const string &symbol_name, bool demangle, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of a given elf file and see if we find a given symbol.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< char ** > &debug_info_root_path, bool read_all_types, bool linux_kernel_mode)
Re-initialize a reader so that it can re-used to read another binary.
unordered_map< string, classes_type > string_classes_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
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.
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
unordered_map< Dwarf_Off, class_or_union_sptr > die_class_or_union_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
unordered_map< Dwarf_Off, function_type_sptr > die_function_type_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< Dwarf_Off, interned_string > die_istring_map_type
Convenience typedef for a map which key is the offset of a DIE and the value is the corresponding qua...
unordered_map< Dwarf_Off, function_decl_sptr > die_function_decl_map_type
Convenience typedef for a map which key the offset of a dwarf die and which value is the correspondin...
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.
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
unordered_map< Dwarf_Off, type_or_decl_base_sptr > die_artefact_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_vector_type, offset_pair_hash > offset_pair_vect_map_type
A convenience typedef for an unordered map that associates a pair of offset_type to a vector of pairs...
unordered_map< interned_string, function_type_sptr, hash_interned_string > istring_fn_type_map_type
Convenience typedef for a map that associates an interned_string to a function_type_sptr.
unordered_map< Dwarf_Off, class_decl_sptr > die_class_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
unordered_map< string, classes_or_unions_type > string_classes_or_unions_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
unordered_map< Dwarf_Off, Dwarf_Off > offset_offset_map_type
Convenience typedef for a map which key is a dwarf offset. The value is also a dwarf offset.
unordered_set< std::pair< offset_type, offset_type >, offset_pair_hash > offset_pair_set_type
A convenience typedef for an unordered set of pairs of offset_type.
unordered_map< string, enums_type > string_enums_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, bool linux_kernel_mode)
Create a dwarf::reader.
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section,...
unordered_map< interned_string, dwarf_offsets_type, hash_interned_string > istring_dwarf_offsets_map_type
Convenience typedef for a map which is an interned_string and which value is a vector of offsets.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
corpus_sptr read_corpus_from_elf(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, fe_iface::status &status)
Read all abigail::translation_unit possible from the debug info accessible from an elf file,...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
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.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
void 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.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
method_decl_sptr copy_member_function(const class_or_union_sptr &t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_opaque, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
bool load_undefined_interfaces
If this option is set to true, then the functions and variables that have an undefined symbol are goi...
A functor to hash instances of interned_string.