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);
383die_is_anonymous(
const Dwarf_Die* die);
386die_is_anonymous_data_member(
const Dwarf_Die* die);
389die_is_type(
const Dwarf_Die* die);
392die_is_decl(
const Dwarf_Die* die);
395die_is_declaration_only(Dwarf_Die* die);
398die_is_variable_decl(
const Dwarf_Die *die);
401die_is_function_decl(
const Dwarf_Die *die);
404die_has_size_attribute(
const Dwarf_Die *die);
407die_has_no_child(
const Dwarf_Die *die);
410die_is_namespace(
const Dwarf_Die* die);
413die_is_unspecified(Dwarf_Die* die);
416die_is_void_type(Dwarf_Die* die);
419die_is_pointer_type(
const Dwarf_Die* die);
422pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
425die_is_reference_type(
const Dwarf_Die* die);
428die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
431die_is_pointer_or_reference_type(
const Dwarf_Die* die);
434die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
437die_is_class_type(
const Dwarf_Die* die);
440die_is_qualified_type(
const Dwarf_Die* die);
443die_is_function_type(
const Dwarf_Die *die);
446die_has_object_pointer(
const Dwarf_Die* die,
447 Dwarf_Die& object_pointer);
450die_has_children(
const Dwarf_Die* die);
453die_this_pointer_from_object_pointer(Dwarf_Die* die,
454 Dwarf_Die& this_pointer);
457die_this_pointer_is_const(Dwarf_Die* die);
460die_object_pointer_is_for_const_method(Dwarf_Die* die);
463is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
466die_is_at_class_scope(
const reader& rdr,
467 const Dwarf_Die* die,
469 Dwarf_Die& class_scope_die);
471eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
474 bool& is_tls_address);
477dwarf_language_to_tu_language(
size_t l);
480die_unsigned_constant_attribute(
const Dwarf_Die* die,
485die_signed_constant_attribute(
const Dwarf_Die*die,
490die_constant_attribute(
const Dwarf_Die *die,
493 array_type_def::subrange_type::bound_value &value);
496die_member_offset(
const reader& rdr,
497 const Dwarf_Die* die,
501form_is_DW_FORM_strx(
unsigned form);
504form_is_DW_FORM_line_strp(
unsigned form);
507die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
510die_name(
const Dwarf_Die* die);
513die_location(
const reader& rdr,
const Dwarf_Die* die);
516die_location_address(Dwarf_Die* die,
518 bool& is_tls_address);
521die_die_attribute(
const Dwarf_Die* die,
524 bool recursively =
true);
527subrange_die_indirect_bound_value(
const Dwarf_Die *die,
529 array_type_def::subrange_type::bound_value& v,
533subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
535 Dwarf_Die& referenced_subrange);
537get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
540build_internal_anonymous_die_name(
const string &base_name,
541 size_t anonymous_type_index);
544get_internal_anonymous_die_name(Dwarf_Die *die,
545 size_t anonymous_type_index);
548die_qualified_type_name(
const reader& rdr,
549 const Dwarf_Die* die,
553die_qualified_decl_name(
const reader& rdr,
554 const Dwarf_Die* die,
558die_qualified_name(
const reader& rdr,
559 const Dwarf_Die* die,
563die_qualified_type_name_empty(
const reader& rdr,
564 const Dwarf_Die* die,
size_t where,
565 string &qualified_name);
568die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
569 const Dwarf_Die* die,
572 string &return_type_name,
574 vector<string>& parm_names,
579die_function_signature(
const reader& rdr,
580 const Dwarf_Die *die,
581 size_t where_offset);
584die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
587die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
590die_function_type_is_method_type(
const reader& rdr,
591 const Dwarf_Die *die,
593 Dwarf_Die& object_pointer_die,
594 Dwarf_Die& class_die,
598die_pretty_print_type(reader& rdr,
599 const Dwarf_Die* die,
600 size_t where_offset);
603die_pretty_print_decl(reader& rdr,
604 const Dwarf_Die* die,
605 size_t where_offset);
608die_pretty_print(reader& rdr,
609 const Dwarf_Die* die,
610 size_t where_offset);
613maybe_canonicalize_type(
const type_base_sptr& t,
622 imported_unit_points_type::const_iterator&);
625build_subrange_type(reader& rdr,
626 const Dwarf_Die* die,
628 bool associate_type_to_die =
true);
631build_subranges_from_array_type_die(reader& rdr,
632 const Dwarf_Die* die,
635 bool associate_type_to_die =
true);
638compare_dies(
const reader& rdr,
639 const Dwarf_Die *l,
const Dwarf_Die *r,
640 bool update_canonical_dies_on_the_fly);
643compare_dies_during_canonicalization(reader& rdr,
644 const Dwarf_Die *l,
const Dwarf_Die *r,
645 bool update_canonical_dies_on_the_fly);
648get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
662compare_symbol_name(
const string& symbol_name,
671 return symbol_name == name;
700lookup_symbol_from_sysv_hash_tab(
const environment& env,
702 const string& sym_name,
704 size_t sym_tab_index,
706 vector<elf_symbol_sptr>& syms_found)
708 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
711 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
714 GElf_Shdr sheader_mem;
715 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
717 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
722 unsigned long hash = elf_hash(sym_name.c_str());
723 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
724 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
725 size_t nb_buckets = ht_data[0];
726 size_t nb_chains = ht_data[1];
734 Elf32_Word* ht_buckets = &ht_data[2];
735 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
738 size_t bucket = hash % nb_buckets;
739 size_t symbol_index = ht_buckets[bucket];
742 const char* sym_name_str;
751 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
752 sym_name_str = elf_strptr(elf_handle,
753 sym_tab_section_header->sh_link,
756 && compare_symbol_name(sym_name_str, sym_name, demangle))
762 sym_size = symbol.st_size;
763 elf_symbol::version ver;
774 symbol.st_shndx != SHN_UNDEF,
775 symbol.st_shndx == SHN_COMMON,
776 ver, sym_visibility);
777 syms_found.push_back(symbol_found);
780 symbol_index = ht_chains[symbol_index];
781 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
792get_elf_class_size_in_bytes(Elf* elf_handle)
798 int c = hdr.e_ident[EI_CLASS];
832bloom_word_at(Elf* elf_handle,
833 Elf32_Word* bloom_filter,
836 Elf64_Xword result = 0;
840 c = h.e_ident[EI_CLASS];
845 result = bloom_filter[index];
849 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
870 size_t first_sym_index;
873 Elf32_Word* bloom_filter;
876 Elf_Scn* sym_tab_section;
877 GElf_Shdr sym_tab_section_header;
907setup_gnu_ht(Elf* elf_handle,
909 size_t sym_tab_index,
912 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
914 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
916 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
917 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
922 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
923 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
925 ht.nb_buckets = ht_data[0];
926 if (ht.nb_buckets == 0)
930 ht.first_sym_index = ht_data[1];
933 ht.bf_nwords = ht_data[2];
935 ht.shift = ht_data[3];
937 ht.bloom_filter = &ht_data[4];
942 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
944 ht.buckets = ht.bloom_filter + ht.bf_size;
946 ht.chain = ht.buckets + ht.nb_buckets;
977lookup_symbol_from_gnu_hash_tab(
const environment& env,
979 const string& sym_name,
981 size_t sym_tab_index,
983 vector<elf_symbol_sptr>& syms_found)
986 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
992 size_t h1 = elf_gnu_hash(sym_name.c_str());
993 size_t h2 = h1 >> ht.shift;
996 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
997 int n = (h1 / c) % ht.bf_nwords;
1003 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1006 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1009 size_t i = ht.buckets[h1 % ht.nb_buckets];
1013 Elf32_Word stop_word, *stop_wordp;
1014 elf_symbol::version ver;
1016 const char* sym_name_str;
1025 for (i = ht.buckets[h1 % ht.nb_buckets],
1026 stop_wordp = &ht.chain[i - ht.first_sym_index];
1029 < ht.chain + (ht.sym_count - ht.first_sym_index));
1032 stop_word = *stop_wordp;
1033 if ((stop_word & ~ 1)!= (h1 & ~1))
1039 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1041 sym_name_str = elf_strptr(elf_handle,
1042 ht.sym_tab_section_header.sh_link,
1045 && compare_symbol_name(sym_name_str, sym_name, demangle))
1063 sym_type, sym_binding,
1064 symbol.st_shndx != SHN_UNDEF,
1065 symbol.st_shndx == SHN_COMMON,
1066 ver, sym_visibility);
1067 syms_found.push_back(symbol_found);
1109lookup_symbol_from_elf_hash_tab(
const environment& env,
1111 hash_table_kind ht_kind,
1113 size_t symtab_index,
1114 const string& symbol_name,
1116 vector<elf_symbol_sptr>& syms_found)
1118 if (elf_handle == 0 || symbol_name.empty())
1121 if (ht_kind == NO_HASH_TABLE_KIND)
1124 if (ht_kind == SYSV_HASH_TABLE_KIND)
1125 return lookup_symbol_from_sysv_hash_tab(env,
1126 elf_handle, symbol_name,
1131 else if (ht_kind == GNU_HASH_TABLE_KIND)
1132 return lookup_symbol_from_gnu_hash_tab(env,
1133 elf_handle, symbol_name,
1166lookup_symbol_from_symtab(
const environment& env,
1168 const string& sym_name,
1169 size_t sym_tab_index,
1171 vector<elf_symbol_sptr>& syms_found)
1176 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1179 GElf_Shdr header_mem;
1180 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1183 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1184 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1187 elf_symbol::version ver;
1190 for (
size_t i = 0; i < symcount; ++i)
1193 sym = gelf_getsym(symtab, i, &sym_mem);
1194 name_str = elf_strptr(elf_handle,
1195 sym_tab_header->sh_link,
1198 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1206 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1207 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1216 sym_binding, sym_is_defined,
1217 sym_is_common, ver, sym_visibility);
1218 syms_found.push_back(symbol_found);
1257lookup_symbol_from_elf(
const environment& env,
1259 const string& symbol_name,
1261 vector<elf_symbol_sptr>& syms_found)
1263 size_t hash_table_index = 0, symbol_table_index = 0;
1264 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1269 symbol_table_index);
1271 if (ht_kind == NO_HASH_TABLE_KIND)
1276 return lookup_symbol_from_symtab(env,
1284 return lookup_symbol_from_elf_hash_tab(env,
1308lookup_public_function_symbol_from_elf(environment& env,
1310 const string& symbol_name,
1311 vector<elf_symbol_sptr>& func_syms)
1313 vector<elf_symbol_sptr> syms_found;
1316 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1319 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1320 i != syms_found.end();
1326 if ((type == elf_symbol::FUNC_TYPE
1327 || type == elf_symbol::GNU_IFUNC_TYPE
1328 || type == elf_symbol::COMMON_TYPE)
1329 && (binding == elf_symbol::GLOBAL_BINDING
1330 || binding == elf_symbol::WEAK_BINDING))
1332 func_syms.push_back(*i);
1353 int64_t const_value_;
1361 expr_result(
bool is_const)
1362 : is_const_(is_const),
1366 explicit expr_result(int64_t v)
1392 const_value(int64_t& value)
1396 value = const_value_;
1412 return const_value_;
1415 operator int64_t()
const
1416 {
return const_value();}
1419 operator=(
const int64_t v)
1427 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1430 operator>=(
const expr_result& o)
const
1431 {
return const_value_ >= o.const_value_;}
1434 operator<=(
const expr_result& o)
const
1435 {
return const_value_ <= o.const_value_;}
1438 operator>(
const expr_result& o)
const
1439 {
return const_value_ > o.const_value_;}
1442 operator<(
const expr_result& o)
const
1443 {
return const_value_ < o.const_value_;}
1448 expr_result r(*
this);
1449 r.const_value_ += v.const_value_;
1450 r.is_const_ = r.is_const_ && v.is_const_;
1455 operator+=(int64_t v)
1462 operator-(
const expr_result& v)
const
1464 expr_result r(*
this);
1465 r.const_value_ -= v.const_value_;
1466 r.is_const_ = r.is_const_ && v.is_const_;
1471 operator%(
const expr_result& v)
const
1473 expr_result r(*
this);
1474 r.const_value_ %= v.const_value_;
1475 r.is_const_ = r.is_const_ && v.is_const();
1480 operator*(
const expr_result& v)
const
1482 expr_result r(*
this);
1483 r.const_value_ *= v.const_value_;
1484 r.is_const_ = r.is_const_ && v.is_const();
1491 expr_result r(*
this);
1492 r.const_value_ |= v.const_value_;
1493 r.is_const_ = r.is_const_ && v.is_const_;
1498 operator^(
const expr_result& v)
const
1500 expr_result r(*
this);
1501 r.const_value_ ^= v.const_value_;
1502 r.is_const_ = r.is_const_ && v.is_const_;
1507 operator>>(
const expr_result& v)
const
1509 expr_result r(*
this);
1510 r.const_value_ = r.const_value_ >> v.const_value_;
1511 r.is_const_ = r.is_const_ && v.is_const_;
1518 expr_result r(*
this);
1519 r.const_value_ = r.const_value_ << v.const_value_;
1520 r.is_const_ = r.is_const_ && v.is_const_;
1527 expr_result r(*
this);
1528 r.const_value_ = ~r.const_value_;
1535 expr_result r(*
this);
1536 r.const_value_ = -r.const_value_;
1543 expr_result r = *
this;
1544 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1551 expr_result r(*
this);
1552 r.const_value_ &= o.const_value_;
1553 r.is_const_ = r.is_const_ && o.is_const_;
1558 operator/(
const expr_result& o)
1560 expr_result r(*
this);
1561 r.is_const_ = r.is_const_ && o.is_const_;
1562 return r.const_value() / o.const_value();
1568class expr_result_stack_type
1570 vector<expr_result> elems_;
1574 expr_result_stack_type()
1575 {elems_.reserve(4);}
1578 operator[](
unsigned i)
1580 unsigned s = elems_.size();
1582 return elems_[s - 1 -i];
1586 operator[](
unsigned i)
const
1587 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1591 {
return elems_.size();}
1593 vector<expr_result>::reverse_iterator
1595 {
return elems_.rbegin();}
1597 const vector<expr_result>::reverse_iterator
1599 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1601 vector<expr_result>::reverse_iterator
1603 {
return elems_.rend();}
1605 const vector<expr_result>::reverse_iterator
1607 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1611 {
return elems_.back();}
1615 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1618 push_front(expr_result e)
1619 {elems_.push_back(e);}
1624 expr_result r = front();
1630 erase(vector<expr_result>::reverse_iterator i)
1631 {elems_.erase(--i.base());}
1639struct dwarf_expr_eval_context
1642 expr_result_stack_type stack;
1647 dwarf_expr_eval_context()
1651 stack.push_front(expr_result(
true));
1658 stack.push_front(expr_result(
true));
1659 accum = expr_result(
false);
1660 set_tls_addr =
false;
1669 set_tls_address(
bool f)
1678 set_tls_address()
const
1679 {
return set_tls_addr;}
1684 expr_result r = stack.front();
1690 push(
const expr_result& v)
1691 {stack.push_front(v);}
1700typedef shared_ptr<reader> reader_sptr;
1707class reader :
public elf_based_reader
1714 template <
typename ContainerType>
1715 class die_source_dependant_container_set
1717 ContainerType primary_debug_info_container_;
1718 ContainerType alt_debug_info_container_;
1719 ContainerType type_unit_container_;
1733 ContainerType *result = 0;
1736 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1737 result = &primary_debug_info_container_;
1739 case ALT_DEBUG_INFO_DIE_SOURCE:
1740 result = &alt_debug_info_container_;
1742 case TYPE_UNIT_DIE_SOURCE:
1743 result = &type_unit_container_;
1745 case NO_DEBUG_INFO_DIE_SOURCE:
1746 case NUMBER_OF_DIE_SOURCES:
1759 const ContainerType&
1762 return const_cast<die_source_dependant_container_set*
>(
this)->
1763 get_container(source);
1777 get_container(
const reader& rdr,
const Dwarf_Die *die)
1779 const die_source source = rdr.get_die_source(die);
1780 return get_container(source);
1793 const ContainerType&
1794 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1796 return const_cast<die_source_dependant_container_set*
>(
this)->
1797 get_container(rdr, die);
1804 primary_debug_info_container_.clear();
1805 alt_debug_info_container_.clear();
1806 type_unit_container_.clear();
1810 unsigned short dwarf_version_;
1811 Dwarf_Die* cur_tu_die_;
1812 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1816 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1817 decl_die_repr_die_offsets_maps_;
1821 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1822 type_die_repr_die_offsets_maps_;
1823 mutable die_source_dependant_container_set<die_istring_map_type>
1824 die_qualified_name_maps_;
1825 mutable die_source_dependant_container_set<die_istring_map_type>
1826 die_pretty_repr_maps_;
1827 mutable die_source_dependant_container_set<die_istring_map_type>
1828 die_pretty_type_repr_maps_;
1831 mutable die_source_dependant_container_set<die_artefact_map_type>
1832 decl_die_artefact_maps_;
1835 mutable die_source_dependant_container_set<die_artefact_map_type>
1836 type_die_artefact_maps_;
1839 mutable die_source_dependant_container_set<offset_offset_map_type>
1840 canonical_type_die_offsets_;
1843 mutable die_source_dependant_container_set<offset_offset_map_type>
1844 canonical_decl_die_offsets_;
1850 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1852 dwarf_offset_pair_hash> die_comparison_results_;
1862 vector<type_base_sptr> types_to_canonicalize_;
1881 list<var_decl_sptr> var_decls_to_add_;
1882#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1883 bool debug_die_canonicalization_is_on_;
1884 bool use_canonical_die_comparison_;
1886 mutable size_t compare_count_;
1887 mutable size_t canonical_propagated_count_;
1888 mutable size_t cancelled_propagation_count_;
1889 mutable optional<bool> leverage_dwarf_factorization_;
1924 reader(
const string& elf_path,
1926 environment& environment,
1927 bool load_all_types,
1928 bool linux_kernel_mode)
1933 initialize(load_all_types, linux_kernel_mode);
1951 initialize(
bool load_all_types,
bool linux_kernel_mode)
1955 decl_die_repr_die_offsets_maps_.clear();
1956 type_die_repr_die_offsets_maps_.clear();
1957 die_qualified_name_maps_.clear();
1958 die_pretty_repr_maps_.clear();
1959 die_pretty_type_repr_maps_.clear();
1960 decl_die_artefact_maps_.clear();
1961 type_die_artefact_maps_.clear();
1962 canonical_type_die_offsets_.clear();
1963 canonical_decl_die_offsets_.clear();
1964 die_wip_classes_map_.clear();
1965 alternate_die_wip_classes_map_.clear();
1966 type_unit_die_wip_classes_map_.clear();
1967 die_wip_function_types_map_.clear();
1968 alternate_die_wip_function_types_map_.clear();
1969 type_unit_die_wip_function_types_map_.clear();
1970 die_function_with_no_symbol_map_.clear();
1971 types_to_canonicalize_.clear();
1972 decl_only_classes_map_.clear();
1973 die_tu_map_.clear();
1977 primary_die_parent_map_.clear();
1978 tu_die_imported_unit_points_map_.clear();
1979 alt_tu_die_imported_unit_points_map_.clear();
1980 type_units_tu_die_imported_unit_points_map_.clear();
1981 alternate_die_parent_map_.clear();
1982 type_section_die_parent_map_.clear();
1983 var_decls_to_add_.clear();
1984 clear_per_translation_unit_data();
1985 options().load_in_linux_kernel_mode = linux_kernel_mode;
1986 options().load_all_types = load_all_types;
1987#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1988 debug_die_canonicalization_is_on_ =
1989 env().debug_die_canonicalization_is_on();
1990 use_canonical_die_comparison_ =
true;
1993 canonical_propagated_count_ = 0;
1994 cancelled_propagation_count_ = 0;
1995 load_in_linux_kernel_mode(linux_kernel_mode);
2016 initialize(
const string& elf_path,
2018 bool load_all_types,
2019 bool linux_kernel_mode)
2022 initialize(load_all_types, linux_kernel_mode);
2042 static dwarf::reader_sptr
2043 create(
const std::string& elf_path,
2045 environment& environment,
2046 bool load_all_types,
2047 bool linux_kernel_mode)
2050 environment, load_all_types,
2051 linux_kernel_mode));
2080 return corpus_sptr();
2098 return corpus_sptr();
2102 corpus_sptr corp = read_debug_info_into_corpus();
2117 read_debug_info_into_corpus()
2119 clear_per_corpus_data();
2124 origin |= corpus::DWARF_ORIGIN;
2125 corpus()->set_origin(origin);
2127 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2128 && !env().user_set_analyze_exported_interfaces_only())
2135 env().analyze_exported_interfaces_only(
true);
2146 || !
corpus()->get_symtab()->has_symbols())
2149 uint8_t address_size = 0;
2150 size_t header_size = 0;
2152#ifdef WITH_DEBUG_SELF_COMPARISON
2153 if (env().self_comparison_debug_is_on())
2154 env().set_self_comparison_debug_input(
corpus());
2160 tools_utils::timer t;
2163 cerr <<
"building die -> parent maps ...";
2167 build_die_parent_maps();
2172 cerr <<
" DONE@" <<
corpus()->get_path()
2179 env().canonicalization_is_done(
false);
2182 tools_utils::timer t;
2185 cerr <<
"building the libabigail internal representation ...";
2189 Dwarf_Half dwarf_vers = 0;
2190 for (Dwarf_Off offset = 0, next_offset = 0;
2192 offset, &next_offset, &header_size,
2193 &dwarf_vers, NULL, &address_size, NULL,
2195 offset = next_offset)
2197 Dwarf_Off die_offset = offset + header_size;
2201 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2204 dwarf_version(dwarf_vers);
2211 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2217 cerr <<
" DONE@" <<
corpus()->get_path()
2222 cerr <<
"Number of aggregate types compared: "
2223 << compare_count_ <<
"\n"
2224 <<
"Number of canonical types propagated: "
2225 << canonical_propagated_count_ <<
"\n"
2226 <<
"Number of cancelled propagated canonical types:"
2227 << cancelled_propagation_count_ <<
"\n";
2232 tools_utils::timer t;
2235 cerr <<
"resolving declaration only classes ...";
2238 resolve_declaration_only_classes();
2242 cerr <<
" DONE@" <<
corpus()->get_path()
2250 tools_utils::timer t;
2253 cerr <<
"resolving declaration only enums ...";
2256 resolve_declaration_only_enums();
2260 cerr <<
" DONE@" <<
corpus()->get_path()
2268 tools_utils::timer t;
2271 cerr <<
"fixing up functions with linkage name but "
2272 <<
"no advertised underlying symbols ....";
2275 fixup_functions_with_no_symbols();
2279 cerr <<
" DONE@" <<
corpus()->get_path()
2298 tools_utils::timer t;
2301 cerr <<
"perform late type canonicalizing ...\n";
2305 perform_late_type_canonicalizing();
2309 cerr <<
"late type canonicalizing DONE@"
2317 env().canonicalization_is_done(
true);
2320 tools_utils::timer t;
2323 cerr <<
"sort functions and variables ...";
2326 corpus()->sort_functions();
2327 corpus()->sort_variables();
2331 cerr <<
" DONE@" <<
corpus()->get_path()
2345 clear_per_translation_unit_data()
2347 while (!scope_stack().empty())
2348 scope_stack().pop();
2349 var_decls_to_re_add_to_tree().clear();
2350 per_tu_repr_to_fn_type_maps().clear();
2356 clear_per_corpus_data()
2358 die_qualified_name_maps_.clear();
2359 die_pretty_repr_maps_.clear();
2360 die_pretty_type_repr_maps_.clear();
2361 clear_types_to_canonicalize();
2376 {
return const_cast<reader*
>(
this)->env();}
2384 drop_undefined_syms()
const
2385 {
return options().drop_undefined_syms;}
2392 drop_undefined_syms(
bool f)
2393 {
options().drop_undefined_syms = f;}
2397 dwarf_version()
const
2398 {
return dwarf_version_;}
2401 dwarf_version(
unsigned short v)
2402 {dwarf_version_ = v;}
2414 dwarf_elf_handle()
const
2425 dwarf_is_splitted()
const
2435 dwarf_per_die_source(
die_source source)
const
2437 const Dwarf *result = 0;
2440 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2441 case TYPE_UNIT_DIE_SOURCE:
2444 case ALT_DEBUG_INFO_DIE_SOURCE:
2447 case NO_DEBUG_INFO_DIE_SOURCE:
2448 case NUMBER_OF_DIE_SOURCES:
2463 {
return cur_tu_die_;}
2466 cur_tu_die(Dwarf_Die* cur_tu_die)
2467 {cur_tu_die_ = cur_tu_die;}
2469 dwarf_expr_eval_context&
2470 dwarf_expr_eval_ctxt()
const
2471 {
return dwarf_expr_eval_context_;}
2478 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2479 decl_die_repr_die_offsets_maps()
const
2480 {
return decl_die_repr_die_offsets_maps_;}
2487 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2488 decl_die_repr_die_offsets_maps()
2489 {
return decl_die_repr_die_offsets_maps_;}
2496 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2497 type_die_repr_die_offsets_maps()
const
2498 {
return type_die_repr_die_offsets_maps_;}
2505 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2506 type_die_repr_die_offsets_maps()
2507 {
return type_die_repr_die_offsets_maps_;}
2520 compute_canonical_die_offset(
const Dwarf_Die *die,
2521 Dwarf_Off &canonical_die_offset,
2522 bool die_as_type)
const
2526 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2527 get_container(*
this, die)
2528 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2529 get_container(*
this, die);
2531 Dwarf_Die canonical_die;
2532 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2534 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2552 compute_canonical_die(
const Dwarf_Die *die,
2554 Dwarf_Die &canonical_die,
2555 bool die_as_type)
const
2557 const die_source source = get_die_source(die);
2559 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2561 compute_canonical_die(die_offset, source,
2563 canonical_die, die_as_type);
2583 compute_canonical_die(Dwarf_Off die_offset,
2586 Dwarf_Die &canonical_die,
2587 bool die_as_type)
const
2593 ? (
const_cast<reader*
>(
this)->
2594 type_die_repr_die_offsets_maps().get_container(source))
2595 : (
const_cast<reader*
>(
this)->
2596 decl_die_repr_die_offsets_maps().get_container(source));
2599 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2608 interned_string name =
2610 ? get_die_pretty_type_representation(&die, 0)
2611 : get_die_pretty_representation(&die, 0);
2613 Dwarf_Off canonical_die_offset = 0;
2614 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2618 offsets.push_back(die_offset);
2619 map[name] = offsets;
2620 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2621 get_die_from_offset(source, die_offset, &canonical_die);
2625 Dwarf_Off cur_die_offset;
2626 Dwarf_Die potential_canonical_die;
2627 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2628 o != i->second.end();
2631 cur_die_offset = *o;
2632 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2633 if (compare_dies(*
this, &die, &potential_canonical_die,
2636 canonical_die_offset = cur_die_offset;
2637 set_canonical_die_offset(canonical_dies, die_offset,
2638 canonical_die_offset);
2639 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2644 canonical_die_offset = die_offset;
2645 i->second.push_back(die_offset);
2646 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2647 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2666 get_canonical_die(
const Dwarf_Die *die,
2667 Dwarf_Die &canonical_die,
2671 const die_source source = get_die_source(die);
2675 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2676 get_container(source)
2677 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2678 get_container(source);
2680 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2681 if (Dwarf_Off canonical_die_offset =
2682 get_canonical_die_offset(canonical_dies, die_offset))
2684 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2692 ? (
const_cast<reader*
>(
this)->
2693 type_die_repr_die_offsets_maps().get_container(*
this, die))
2694 : (
const_cast<reader*
>(
this)->
2695 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2703 interned_string name =
2705 ? get_die_pretty_type_representation(die, where)
2706 : get_die_pretty_representation(die, where);
2708 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2712 Dwarf_Off cur_die_offset;
2713 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2714 o != i->second.end();
2717 cur_die_offset = *o;
2718 get_die_from_offset(source, cur_die_offset, &canonical_die);
2720 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2721 die, &canonical_die,
2724 set_canonical_die_offset(canonical_dies,
2758 get_or_compute_canonical_die(
const Dwarf_Die* die,
2759 Dwarf_Die& canonical_die,
2761 bool die_as_type)
const
2763 const die_source source = get_die_source(die);
2767 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2768 get_container(source)
2769 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2770 get_container(source);
2772 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2774 if (Dwarf_Off canonical_die_offset =
2775 get_canonical_die_offset(canonical_dies,
2776 initial_die_offset))
2778 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2782 if (!is_type_die_to_be_canonicalized(die))
2789 ? (
const_cast<reader*
>(
this)->
2790 type_die_repr_die_offsets_maps().get_container(*
this, die))
2791 : (
const_cast<reader*
>(
this)->
2792 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2800 interned_string name =
2802 ? get_die_pretty_type_representation(die, where)
2803 : get_die_pretty_representation(die, where);
2805 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2809 offsets.push_back(initial_die_offset);
2810 map[name] = offsets;
2811 get_die_from_offset(source, initial_die_offset, &canonical_die);
2812 set_canonical_die_offset(canonical_dies,
2814 initial_die_offset);
2821 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2824 Dwarf_Off die_offset = i->second[n];
2825 get_die_from_offset(source, 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,
2841 get_die_from_offset(source, initial_die_offset, &canonical_die);
2842 i->second.push_back(initial_die_offset);
2843 set_canonical_die_offset(canonical_dies,
2845 initial_die_offset);
2862 get_die_source(
const Dwarf_Die *die)
const
2864 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2885 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2889 uint8_t address_size = 0, offset_size = 0;
2890 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2891 &cu_die, &address_size,
2895 Dwarf_Half version = 0;
2896 Dwarf_Off abbrev_offset = 0;
2897 uint64_t type_signature = 0;
2898 Dwarf_Off type_offset = 0;
2899 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2900 &version, &abbrev_offset,
2901 &address_size, &offset_size,
2902 &type_signature, &type_offset))
2905 int tag = dwarf_tag(&cu_kind);
2907 if (tag == DW_TAG_compile_unit
2908 || tag == DW_TAG_partial_unit)
2910 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2912 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2914 source = ALT_DEBUG_INFO_DIE_SOURCE;
2918 else if (tag == DW_TAG_type_unit)
2919 source = TYPE_UNIT_DIE_SOURCE;
2935 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
2937 if (source == TYPE_UNIT_DIE_SOURCE)
2938 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2941 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2968 associate_die_to_decl(Dwarf_Die* die,
2969 decl_base_sptr decl,
2970 size_t where_offset,
2971 bool do_associate_by_repr =
false)
2973 const die_source source = get_die_source(die);
2976 decl_die_artefact_maps().get_container(source);
2979 if (do_associate_by_repr)
2981 Dwarf_Die equiv_die;
2982 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2985 die_offset = dwarf_dieoffset(&equiv_die);
2988 die_offset = dwarf_dieoffset(die);
2990 m[die_offset] = decl;
3012 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3014 decl_base_sptr result =
3015 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3034 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3038 die_qualified_name_maps_.get_container(*
this, die);
3040 size_t die_offset = dwarf_dieoffset(die);
3041 die_istring_map_type::const_iterator i = map.find(die_offset);
3045 reader& rdr = *
const_cast<reader*
>(
this);
3046 string qualified_name = die_qualified_name(rdr, die, where_offset);
3047 interned_string istr = env().intern(qualified_name);
3048 map[die_offset] = istr;
3068 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3070 return const_cast<reader*
>(
this)->
3071 get_die_qualified_name(die, where_offset);
3092 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3097 if (die == cur_tu_die())
3098 return env().intern(
"");
3101 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3104 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3105 die_istring_map_type::const_iterator i =
3106 map.find(die_offset);
3110 reader& rdr = *
const_cast<reader*
>(
this);
3111 string qualified_name;
3112 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3113 if ((tag == DW_TAG_structure_type
3114 || tag == DW_TAG_class_type
3115 || tag == DW_TAG_union_type)
3116 && die_is_anonymous(die))
3118 location l = die_location(*
this, die);
3119 qualified_name = l ? l.expand() :
"noloc";
3120 qualified_name =
"unnamed-at-" + qualified_name;
3124 die_qualified_type_name(rdr, die, where_offset);
3126 interned_string istr = env().intern(qualified_name);
3127 map[die_offset] = istr;
3151 get_die_pretty_type_representation(
const Dwarf_Die *die,
3152 size_t where_offset)
const
3156 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3159 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3160 die_istring_map_type::const_iterator i = map.find(die_offset);
3164 reader& rdr = *
const_cast<reader*
>(
this);
3165 string pretty_representation =
3166 die_pretty_print_type(rdr, die, where_offset);
3167 interned_string istr = env().intern(pretty_representation);
3168 map[die_offset] = istr;
3188 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3193 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3196 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3197 die_istring_map_type::const_iterator i = map.find(die_offset);
3201 reader& rdr = *
const_cast<reader*
>(
this);
3202 string pretty_representation =
3203 die_pretty_print(rdr, die, where_offset);
3204 interned_string istr = env().intern(pretty_representation);
3205 map[die_offset] = istr;
3229 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3232 lookup_artifact_from_die(die,
true);
3234 return fn->get_type();
3258 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3260 Dwarf_Die equiv_die;
3261 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3266 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3267 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3269 size_t die_offset = dwarf_dieoffset(&equiv_die);
3270 die_artefact_map_type::const_iterator i = m.find(die_offset);
3297 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3299 bool die_as_type =
false)
const
3303 ? type_die_artefact_maps().get_container(source)
3304 : decl_die_artefact_maps().get_container(source);
3306 die_artefact_map_type::const_iterator i = m.find(die_offset);
3323 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
3326 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3329 lang = dwarf_language_to_tu_language(l);
3341 die_is_in_c(
const Dwarf_Die *die)
const
3344 if (!get_die_language(die, l))
3357 die_is_in_cplus_plus(
const Dwarf_Die *die)
const
3360 if (!get_die_language(die, l))
3373 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
const
3376 if (!get_die_language(die, l))
3418 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3433 if (!get_die_language(die, lang))
3444 die_source_dependant_container_set<die_artefact_map_type>&
3445 decl_die_artefact_maps()
3446 {
return decl_die_artefact_maps_;}
3453 const die_source_dependant_container_set<die_artefact_map_type>&
3454 decl_die_artefact_maps()
const
3455 {
return decl_die_artefact_maps_;}
3462 die_source_dependant_container_set<die_artefact_map_type>&
3463 type_die_artefact_maps()
3464 {
return type_die_artefact_maps_;}
3471 const die_source_dependant_container_set<die_artefact_map_type>&
3472 type_die_artefact_maps()
const
3473 {
return type_die_artefact_maps_;}
3481 per_tu_repr_to_fn_type_maps()
3482 {
return per_tu_repr_to_fn_type_maps_;}
3490 per_tu_repr_to_fn_type_maps()
const
3491 {
return per_tu_repr_to_fn_type_maps_;}
3501 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3504 if (!die_is_function_type(die))
3507 interned_string repr =
3508 get_die_pretty_type_representation(die, 0);
3511 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3522 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3524 if (!die_is_function_type(die))
3527 interned_string repr = die_name(die).empty() ?
3528 get_die_pretty_type_representation(die, 0)
3529 : get_die_pretty_representation(die, 0);
3532 istring_fn_type_map_type::const_iterator i =
3533 per_tu_repr_to_fn_type_maps().find(repr);
3535 if (i == per_tu_repr_to_fn_type_maps().end())
3552 Dwarf_Off die_offset,
3553 Dwarf_Off canonical_die_offset)
const
3555 canonical_dies[die_offset] = canonical_die_offset;}
3571 set_canonical_die_offset(Dwarf_Off die_offset,
3573 Dwarf_Off canonical_die_offset,
3574 bool die_as_type)
const
3578 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3579 get_container(source)
3580 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3581 get_container(source);
3583 set_canonical_die_offset(canonical_dies,
3585 canonical_die_offset);
3599 set_canonical_die_offset(
const Dwarf_Die *die,
3600 Dwarf_Off canonical_die_offset,
3601 bool die_as_type)
const
3603 const die_source source = get_die_source(die);
3605 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3607 set_canonical_die_offset(die_offset, source,
3608 canonical_die_offset,
3622 Dwarf_Off die_offset)
const
3624 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3625 if (it == canonical_dies.end())
3642 get_canonical_die_offset(Dwarf_Off die_offset,
3644 bool die_as_type)
const
3648 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3649 get_container(source)
3650 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3651 get_container(source);
3653 return get_canonical_die_offset(canonical_dies, die_offset);
3668 erase_canonical_die_offset(Dwarf_Off die_offset,
3670 bool die_as_type)
const
3674 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3675 get_container(source)
3676 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3677 get_container(source);
3679 return canonical_dies.erase(die_offset);
3692 associate_die_to_type(
const Dwarf_Die *die,
3693 type_base_sptr type,
3699 Dwarf_Die equiv_die;
3700 if (!get_or_compute_canonical_die(die, equiv_die, where,
3705 type_die_artefact_maps().get_container(*
this, &equiv_die);
3707 size_t die_offset = dwarf_dieoffset(&equiv_die);
3708 m[die_offset] = type;
3722 lookup_type_from_die(
const Dwarf_Die* die)
const
3725 lookup_artifact_from_die(die,
true);
3727 return fn->get_type();
3745 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3747 type_base_sptr result;
3749 type_die_artefact_maps().get_container(source);
3750 die_artefact_map_type::const_iterator i = m.find(die_offset);
3754 return fn->get_type();
3762 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3772 die_wip_function_types_map(source);
3773 die_function_type_map_type::const_iterator i = m.find(die_offset);
3792 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3807 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3809 case ALT_DEBUG_INFO_DIE_SOURCE:
3810 return alternate_die_wip_classes_map_;
3811 case TYPE_UNIT_DIE_SOURCE:
3812 return type_unit_die_wip_classes_map_;
3813 case NO_DEBUG_INFO_DIE_SOURCE:
3814 case NUMBER_OF_DIE_SOURCES:
3817 return die_wip_classes_map_;
3828 die_wip_function_types_map(
die_source source)
const
3829 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3839 die_wip_function_types_map(
die_source source)
3843 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3845 case ALT_DEBUG_INFO_DIE_SOURCE:
3846 return alternate_die_wip_function_types_map_;
3847 case TYPE_UNIT_DIE_SOURCE:
3848 return type_unit_die_wip_function_types_map_;
3849 case NO_DEBUG_INFO_DIE_SOURCE:
3850 case NUMBER_OF_DIE_SOURCES:
3853 return die_wip_function_types_map_;
3864 die_function_decl_with_no_symbol_map()
3865 {
return die_function_with_no_symbol_map_;}
3878 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3880 die_class_or_union_map_type::const_iterator i =
3881 die_wip_classes_map(source).find(offset);
3882 return (i != die_wip_classes_map(source).end());
3896 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3898 die_function_type_map_type::const_iterator i =
3899 die_wip_function_types_map(source).find(offset);
3900 return (i != die_wip_function_types_map(source).end());
3919 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3925 || dwarf_tag(die) != DW_TAG_member
3926 || !die_name(die).empty())
3932 if (die_is_anonymous_data_member(die))
3938 int64_t offset_in_bits = 0;
3939 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3943 loc = die_location(*
this, die);
3948 std::ostringstream o;
3949 o <<
"unnamed-dm-@-";
3951 o <<
"offset-" << offset_in_bits <<
"bits";
3953 o <<
"loc-" << loc.expand();
3966 declaration_only_classes()
const
3967 {
return decl_only_classes_map_;}
3977 declaration_only_classes()
3978 {
return decl_only_classes_map_;}
3986 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
3988 if (cou->get_is_declaration_only()
3989 && cou->get_definition_of_declaration() == 0)
3991 string qn = cou->get_qualified_name();
3992 string_classes_or_unions_map::iterator record =
3993 declaration_only_classes().find(qn);
3994 if (record == declaration_only_classes().end())
3995 declaration_only_classes()[qn].push_back(cou);
3997 record->second.push_back(cou);
4009 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4011 if (cou->get_is_declaration_only())
4012 return (declaration_only_classes().find(cou->get_qualified_name())
4013 != declaration_only_classes().end());
4033 const environment& e = l->get_environment();
4036 e.priv_->allow_type_comparison_results_caching(
true);
4037 bool s0 = e.decl_only_class_equals_definition();
4038 e.decl_only_class_equals_definition(
true);
4039 bool equal = l == r;
4040 e.decl_only_class_equals_definition(s0);
4041 e.priv_->clear_type_comparison_results_cache();
4042 e.priv_->allow_type_comparison_results_caching(
false);
4049 resolve_declaration_only_classes()
4051 vector<string> resolved_classes;
4053 for (string_classes_or_unions_map::iterator i =
4054 declaration_only_classes().begin();
4055 i != declaration_only_classes().end();
4058 bool to_resolve =
false;
4059 for (classes_or_unions_type::iterator j = i->second.begin();
4060 j != i->second.end();
4062 if ((*j)->get_is_declaration_only()
4063 && ((*j)->get_definition_of_declaration() == 0))
4068 resolved_classes.push_back(i->first);
4113 map<string, class_or_union_sptr> per_tu_class_map;
4114 for (type_base_wptrs_type::const_iterator c = classes->begin();
4115 c != classes->end();
4122 if (klass->get_is_declaration_only())
4125 string tu_path = klass->get_translation_unit()->get_absolute_path();
4126 if (tu_path.empty())
4132 per_tu_class_map[tu_path] = klass;
4135 if (!per_tu_class_map.empty())
4141 for (classes_or_unions_type::iterator j = i->second.begin();
4142 j != i->second.end();
4145 if ((*j)->get_is_declaration_only()
4146 && ((*j)->get_definition_of_declaration() == 0))
4149 (*j)->get_translation_unit()->get_absolute_path();
4150 map<string, class_or_union_sptr>::const_iterator e =
4151 per_tu_class_map.find(tu_path);
4152 if (e != per_tu_class_map.end())
4153 (*j)->set_definition_of_declaration(e->second);
4154 else if (per_tu_class_map.size() == 1)
4155 (*j)->set_definition_of_declaration
4156 (per_tu_class_map.begin()->second);
4166 class_or_union_sptr>::const_iterator it;
4167 class_or_union_sptr first_class =
4168 per_tu_class_map.begin()->second;
4169 bool all_class_definitions_are_equal =
true;
4170 for (it = per_tu_class_map.begin();
4171 it != per_tu_class_map.end();
4174 if (it == per_tu_class_map.begin())
4178 if (!compare_before_canonicalisation(it->second,
4181 all_class_definitions_are_equal =
false;
4186 if (all_class_definitions_are_equal)
4187 (*j)->set_definition_of_declaration(first_class);
4191 resolved_classes.push_back(i->first);
4195 size_t num_decl_only_classes = declaration_only_classes().size(),
4196 num_resolved = resolved_classes.size();
4198 cerr <<
"resolved " << num_resolved
4199 <<
" class declarations out of "
4200 << num_decl_only_classes
4203 for (vector<string>::const_iterator i = resolved_classes.begin();
4204 i != resolved_classes.end();
4206 declaration_only_classes().erase(*i);
4208 if (show_stats() && !declaration_only_classes().empty())
4210 cerr <<
"Here are the "
4211 << num_decl_only_classes - num_resolved
4212 <<
" unresolved class declarations:\n";
4213 for (string_classes_or_unions_map::iterator i =
4214 declaration_only_classes().begin();
4215 i != declaration_only_classes().end();
4217 cerr <<
" " << i->first <<
"\n";
4229 declaration_only_enums()
const
4230 {
return decl_only_enums_map_;}
4240 declaration_only_enums()
4241 {
return decl_only_enums_map_;}
4251 if (enom->get_is_declaration_only()
4252 && enom->get_definition_of_declaration() == 0)
4254 string qn = enom->get_qualified_name();
4255 string_enums_map::iterator record =
4256 declaration_only_enums().find(qn);
4257 if (record == declaration_only_enums().end())
4258 declaration_only_enums()[qn].push_back(enom);
4260 record->second.push_back(enom);
4274 if (enom->get_is_declaration_only())
4275 return (declaration_only_enums().find(enom->get_qualified_name())
4276 != declaration_only_enums().end());
4289 resolve_declaration_only_enums()
4291 vector<string> resolved_enums;
4293 for (string_enums_map::iterator i =
4294 declaration_only_enums().begin();
4295 i != declaration_only_enums().end();
4298 bool to_resolve =
false;
4299 for (enums_type::iterator j = i->second.begin();
4300 j != i->second.end();
4302 if ((*j)->get_is_declaration_only()
4303 && ((*j)->get_definition_of_declaration() == 0))
4308 resolved_enums.push_back(i->first);
4350 map<string, enum_type_decl_sptr> per_tu_enum_map;
4351 for (type_base_wptrs_type::const_iterator c = enums->begin();
4359 if (enom->get_is_declaration_only())
4362 string tu_path = enom->get_translation_unit()->get_absolute_path();
4363 if (tu_path.empty())
4369 per_tu_enum_map[tu_path] = enom;
4372 if (!per_tu_enum_map.empty())
4378 for (enums_type::iterator j = i->second.begin();
4379 j != i->second.end();
4382 if ((*j)->get_is_declaration_only()
4383 && ((*j)->get_definition_of_declaration() == 0))
4386 (*j)->get_translation_unit()->get_absolute_path();
4387 map<string, enum_type_decl_sptr>::const_iterator e =
4388 per_tu_enum_map.find(tu_path);
4389 if (e != per_tu_enum_map.end())
4390 (*j)->set_definition_of_declaration(e->second);
4391 else if (per_tu_enum_map.size() == 1)
4392 (*j)->set_definition_of_declaration
4393 (per_tu_enum_map.begin()->second);
4405 per_tu_enum_map.begin()->second;
4406 bool all_enum_definitions_are_equal =
true;
4407 for (it = per_tu_enum_map.begin();
4408 it != per_tu_enum_map.end();
4411 if (it == per_tu_enum_map.begin())
4415 if (!compare_before_canonicalisation(it->second,
4418 all_enum_definitions_are_equal =
false;
4423 if (all_enum_definitions_are_equal)
4424 (*j)->set_definition_of_declaration(first_enum);
4428 resolved_enums.push_back(i->first);
4432 size_t num_decl_only_enums = declaration_only_enums().size(),
4433 num_resolved = resolved_enums.size();
4435 cerr <<
"resolved " << num_resolved
4436 <<
" enum declarations out of "
4437 << num_decl_only_enums
4440 for (vector<string>::const_iterator i = resolved_enums.begin();
4441 i != resolved_enums.end();
4443 declaration_only_enums().erase(*i);
4445 if (show_stats() && !declaration_only_enums().empty())
4447 cerr <<
"Here are the "
4448 << num_decl_only_enums - num_resolved
4449 <<
" unresolved enum declarations:\n";
4450 for (string_enums_map::iterator i = declaration_only_enums().begin();
4451 i != declaration_only_enums().end();
4453 cerr <<
" " << i->first <<
"\n";
4469 corpus_sptr corp =
corpus();
4473 string id = fn->get_id_string();
4475 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4480 if (f->get_symbol())
4500 fixup_functions_with_no_symbols()
4502 corpus_sptr corp =
corpus();
4507 die_function_decl_with_no_symbol_map();
4510 cerr << fns_with_no_symbol.size()
4511 <<
" functions to fixup, potentially\n";
4513 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4514 i != fns_with_no_symbol.end();
4517 corp->lookup_function_symbol(i->second->get_linkage_name()))
4532 if (i->second->get_symbol()
4533 || symbol_already_belongs_to_a_function(sym))
4538 i->second->set_symbol(sym);
4541 i->second->set_is_in_public_symbol_table(
true);
4546 cerr <<
"fixed up '"
4547 << i->second->get_pretty_representation()
4548 <<
"' with symbol '"
4549 << sym->get_id_string()
4553 fns_with_no_symbol.clear();
4563 const vector<type_base_sptr>&
4564 types_to_canonicalize()
const
4565 {
return types_to_canonicalize_;}
4569 clear_types_to_canonicalize()
4571 types_to_canonicalize_.clear();
4579 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4581 types_to_canonicalize_.push_back(t);
4591 canonicalize_types_scheduled()
4593 tools_utils::timer cn_timer;
4596 cerr <<
"going to canonicalize types";
4597 corpus_sptr c =
corpus();
4599 cerr <<
" of corpus " <<
corpus()->get_path();
4603 if (!types_to_canonicalize().empty())
4605 types_to_canonicalize().end(),
4606 [](
const vector<type_base_sptr>::const_iterator& i)
4612 cerr <<
"finished canonicalizing types";
4613 corpus_sptr c =
corpus();
4615 cerr <<
" of corpus " <<
corpus()->get_path();
4616 cerr <<
": (" << cn_timer <<
")\n";
4633 add_late_canonicalized_types_stats(
size_t& canonicalized,
4634 size_t& missed)
const
4636 for (
auto t : types_to_canonicalize())
4638 if (t->get_canonical_type())
4648 perform_late_type_canonicalizing()
4650 canonicalize_types_scheduled();
4654 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4655 add_late_canonicalized_types_stats(num_canonicalized,
4657 total = num_canonicalized + num_missed;
4661 cerr <<
" # late canonicalized types: "
4662 << num_canonicalized;
4664 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4666 <<
" # missed canonicalization opportunities: "
4669 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4677 {
return die_tu_map_;}
4681 {
return die_tu_map_;}
4690 tu_die_imported_unit_points_map(
die_source source)
const
4691 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4700 tu_die_imported_unit_points_map(
die_source source)
4704 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4706 case ALT_DEBUG_INFO_DIE_SOURCE:
4707 return alt_tu_die_imported_unit_points_map_;
4708 case TYPE_UNIT_DIE_SOURCE:
4709 return type_units_tu_die_imported_unit_points_map_;
4710 case NO_DEBUG_INFO_DIE_SOURCE:
4711 case NUMBER_OF_DIE_SOURCES:
4715 return tu_die_imported_unit_points_map_;
4733 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4746 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4748 case ALT_DEBUG_INFO_DIE_SOURCE:
4749 return alternate_die_parent_map_;
4750 case TYPE_UNIT_DIE_SOURCE:
4751 return type_section_die_parent_map();
4752 case NO_DEBUG_INFO_DIE_SOURCE:
4753 case NUMBER_OF_DIE_SOURCES:
4756 return primary_die_parent_map_;
4760 type_section_die_parent_map()
const
4761 {
return type_section_die_parent_map_;}
4764 type_section_die_parent_map()
4765 {
return type_section_die_parent_map_;}
4771 cur_transl_unit()
const
4795 global_scope()
const
4796 {
return cur_transl_unit()->get_global_scope();}
4803 {
return nil_scope_;}
4807 {
return scope_stack_;}
4811 {
return scope_stack_;}
4816 if (scope_stack().empty())
4818 if (cur_transl_unit())
4821 return scope_stack().top();
4824 list<var_decl_sptr>&
4825 var_decls_to_re_add_to_tree()
4826 {
return var_decls_to_add_;}
4839 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
4841 if (!die || !die_is_decl(die))
4844 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4845 Dwarf_Addr decl_symbol_address = 0;
4847 if (die_is_variable_decl(die))
4849 if ((address_found = get_variable_address(die, decl_symbol_address)))
4850 symbol_is_exported =
4853 else if (die_is_function_decl(die))
4855 if ((address_found = get_function_address(die, decl_symbol_address)))
4856 symbol_is_exported =
4861 result = symbol_is_exported;
4880 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4886 GElf_Ehdr *elf_header = gelf_getehdr(
elf_handle(), &eh_mem);
4888 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4890 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4892 dwarf_elf_load_address));
4895 if (dwarf_is_splitted()
4896 && (dwarf_elf_load_address != elf_load_address))
4907 addr = addr - dwarf_elf_load_address + elf_load_address;
4933 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4940 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4942 if (elf_header->e_type == ET_REL)
4955 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4980 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
4984 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4986 if (elf_header->e_type == ET_REL)
4999 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5018 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5019 Dwarf_Addr& address)
const
5022 Dwarf_Addr end_addr;
5023 ptrdiff_t offset = 0;
5027 Dwarf_Addr addr = 0, fn_addr = 0;
5028 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5030 fn_addr = maybe_adjust_fn_sym_address(addr);
5037 }
while (offset > 0);
5055 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5057 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5058 DW_AT_low_pc, address))
5064 if (!get_first_exported_fn_address_from_DW_AT_ranges
5065 (
const_cast<Dwarf_Die*
>(function_die),
5069 address = maybe_adjust_fn_sym_address(address);
5088 get_variable_address(
const Dwarf_Die* variable_die,
5089 Dwarf_Addr& address)
const
5091 bool is_tls_address =
false;
5092 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5093 address, is_tls_address))
5095 if (!is_tls_address)
5096 address = maybe_adjust_var_sym_address(address);
5103 corpus::exported_decls_builder*
5104 exported_decls_builder()
5105 {
return corpus()->get_exported_decls_builder().get();}
5113 load_all_types()
const
5114 {
return options().load_all_types;}
5122 load_all_types(
bool f)
5123 {
options().load_all_types = f;}
5126 load_in_linux_kernel_mode()
const
5127 {
return options().load_in_linux_kernel_mode;}
5130 load_in_linux_kernel_mode(
bool f)
5131 {
options().load_in_linux_kernel_mode = f;}
5141 leverage_dwarf_factorization()
const
5143 if (!leverage_dwarf_factorization_.has_value())
5145 if (
options().leverage_dwarf_factorization
5146 && elf_helpers::find_section_by_name(
elf_handle(),
5147 ".gnu_debugaltlink"))
5148 leverage_dwarf_factorization_ =
true;
5150 leverage_dwarf_factorization_ =
false;
5152 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5154 return *leverage_dwarf_factorization_;
5164 {
return options().show_stats;}
5213 build_die_parent_relations_under(Dwarf_Die* die,
5223 if (dwarf_child(die, &child) != 0)
5228 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5229 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5231 Dwarf_Die imported_unit;
5232 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5243 && die_has_children(&imported_unit))
5245 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5246 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5247 imported_units.push_back
5248 (imported_unit_point(dwarf_dieoffset(&child),
5250 imported_unit_die_source));
5253 build_die_parent_relations_under(&child, source, imported_units);
5255 while (dwarf_siblingof(&child, &child) == 0);
5287 case translation_unit::LANG_UNKNOWN:
5288#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5289 case translation_unit::LANG_Mips_Assembler:
5316 build_die_parent_maps()
5318 bool we_do_have_to_build_die_parent_map =
false;
5319 uint8_t address_size = 0;
5320 size_t header_size = 0;
5325 for (Dwarf_Off offset = 0, next_offset = 0;
5327 offset, &next_offset, &header_size,
5328 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5329 offset = next_offset)
5331 Dwarf_Off die_offset = offset + header_size;
5338 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5340 if (do_we_build_die_parent_maps(lang))
5341 we_do_have_to_build_die_parent_map =
true;
5344 if (!we_do_have_to_build_die_parent_map)
5349 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5350 for (Dwarf_Off offset = 0, next_offset = 0;
5352 offset, &next_offset, &header_size,
5353 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5354 offset = next_offset)
5356 Dwarf_Off die_offset = offset + header_size;
5364 tu_die_imported_unit_points_map(source)[die_offset] =
5366 build_die_parent_relations_under(&cu, source, imported_units);
5371 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5374 for (Dwarf_Off offset = 0, next_offset = 0;
5376 offset, &next_offset, &header_size,
5377 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5378 offset = next_offset)
5380 Dwarf_Off die_offset = offset + header_size;
5387 tu_die_imported_unit_points_map(source)[die_offset] =
5389 build_die_parent_relations_under(&cu, source, imported_units);
5394 source = TYPE_UNIT_DIE_SOURCE;
5397 uint64_t type_signature = 0;
5398 Dwarf_Off type_offset;
5399 for (Dwarf_Off offset = 0, next_offset = 0;
5401 offset, &next_offset, &header_size,
5402 NULL, NULL, &address_size, NULL,
5403 &type_signature, &type_offset) == 0);
5404 offset = next_offset)
5406 Dwarf_Off die_offset = offset + header_size;
5414 tu_die_imported_unit_points_map(source)[die_offset] =
5416 build_die_parent_relations_under(&cu, source, imported_units);
5431struct offset_pairs_stack_type
5448 offset_pairs_stack_type(
const reader& rdr)
5474 offset_pair_vector_type::iterator i;
5476 for (i = vect_.begin();i < vect_.end(); ++i)
5480 if (i != vect_.end())
5499 if (set_.find(p) == set_.end())
5526 bool result =
false;
5531 offset_pair_vector_type::const_iterator i;
5532 for (i = vect_.begin(); i != vect_.end(); ++i)
5536 if (i == vect_.end())
5541 for (++i; i != vect_.end(); ++i)
5543 pairs.push_back(*i);
5563 for (
auto type_pair : dependant_types)
5564 dependant_types_[type_pair].push_back(p);
5575 get_pairs_that_depend_on(p, dependant_types);
5578 auto it = redundant_types_.find(p);
5579 if (it == redundant_types_.end())
5581 auto entry = std::make_pair(p, dependant_types);
5582 redundant_types_.insert(entry);
5585 it->second.insert(it->second.end(),
5586 dependant_types.begin(),
5587 dependant_types.end());
5591 record_dependant_types(p, dependant_types);
5602 auto i = redundant_types_.find(p);
5603 if (i != redundant_types_.end())
5616 auto i = dependant_types_.find(p);
5617 if (i == dependant_types_.end())
5635 bool erase_cached_results =
false)
5639 auto redundant_type = redundant_types_.find(p);
5640 if (redundant_type != redundant_types_.end())
5642 for (
auto dependant_type : redundant_type->second)
5646 auto dependant_types_it = dependant_types_.find(dependant_type);
5647 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5651 auto i = dependant_types_it->second.begin();
5652 for (; i!= dependant_types_it->second.end();++i)
5655 if (i != dependant_types_it->second.end())
5656 dependant_types_it->second.erase(i);
5661 if (dependant_types_it->second.empty())
5663 if (erase_cached_results)
5664 rdr_.die_comparison_results_.erase(dependant_type);
5665 dependant_types_.erase(dependant_types_it);
5669 if (erase_cached_results)
5670 rdr_.die_comparison_results_.erase(p);
5671 redundant_types_.erase(p);
5683 {erase_redundant_type_pair_entry(p,
true);}
5696 get_dependant_types(p, dependant_types,
true);
5697 for (
auto dependant_type : dependant_types)
5701 if (rdr_.propagated_types_.find(dependant_type)
5702 != rdr_.propagated_types_.end())
5704 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5705 dependant_type.first.source_,
5707 rdr_.propagated_types_.erase(dependant_type);
5708 rdr_.cancelled_propagation_count_++;
5712 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5713 if (comp_result_it != rdr_.die_comparison_results_.end())
5714 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5718 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5719 if (comp_result_it != rdr_.die_comparison_results_.end())
5726 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5727 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5728 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5731 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5733 rdr_.erase_canonical_die_offset(p.first.offset_,
5736 rdr_.propagated_types_.erase(p);
5737 rdr_.cancelled_propagation_count_++;
5756 bool transitive_closure =
false)
5758 auto i = redundant_types_.find(p);
5759 if (i != redundant_types_.end())
5761 for (
auto dependant_type : i->second)
5762 if (result.find(dependant_type) == result.end())
5764 result.insert(dependant_type);
5765 if (transitive_closure)
5766 get_dependant_types(p, result,
true);
5775build_ir_node_from_die(reader& rdr,
5778 bool called_from_public_decl,
5779 size_t where_offset,
5780 bool is_declaration_only =
true,
5781 bool is_required_decl_spec =
false);
5784build_ir_node_from_die(reader& rdr,
5786 bool called_from_public_decl,
5787 size_t where_offset);
5790add_or_update_class_type(reader& rdr,
5795 bool called_from_public_decl,
5796 size_t where_offset,
5797 bool is_declaration_only);
5799static union_decl_sptr
5800add_or_update_union_type(reader& rdr,
5803 union_decl_sptr union_type,
5804 bool called_from_public_decl,
5805 size_t where_offset,
5806 bool is_declaration_only);
5808static decl_base_sptr
5809build_ir_node_for_void_type(reader& rdr);
5811static decl_base_sptr
5812build_ir_node_for_variadic_parameter_type(reader &rdr);
5815build_function_decl(reader& rdr,
5817 size_t where_offset,
5821function_is_suppressed(
const reader& rdr,
5822 const scope_decl* scope,
5823 Dwarf_Die *function_die,
5824 bool is_declaration_only);
5827build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5830 size_t where_offset,
5831 bool is_declaration_only,
5835build_var_decl(reader& rdr,
5837 size_t where_offset,
5841build_or_get_var_decl_if_not_suppressed(reader& rdr,
5844 size_t where_offset,
5846 bool is_required_decl_spec =
false);
5848variable_is_suppressed(
const reader& rdr,
5849 const scope_decl* scope,
5850 Dwarf_Die *variable_die,
5851 bool is_required_decl_spec =
false);
5854finish_member_function_reading(Dwarf_Die* die,
5856 const class_or_union_sptr klass,
5865die_is_anonymous(
const Dwarf_Die* die)
5867 Dwarf_Attribute attr;
5868 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
5882die_is_anonymous_data_member(
const Dwarf_Die* die)
5885 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
5886 || !die_name(die).empty())
5890 if (!die_die_attribute(die, DW_AT_type, type_die))
5893 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5894 && dwarf_tag(&type_die) != DW_TAG_union_type)
5911die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5916 Dwarf_Attribute attr;
5917 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5920 const char* str = dwarf_formstring(&attr);
5921 return str ? str :
"";
5935die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5940 Dwarf_Attribute attr;
5941 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5944 const char* str = dwarf_formstring(&attr);
5964die_unsigned_constant_attribute(
const Dwarf_Die* die,
5971 Dwarf_Attribute attr;
5972 Dwarf_Word result = 0;
5973 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
5974 || dwarf_formudata(&attr, &result))
5994die_signed_constant_attribute(
const Dwarf_Die *die,
6001 Dwarf_Attribute attr;
6002 Dwarf_Sword result = 0;
6003 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6004 || dwarf_formsdata(&attr, &result))
6030die_constant_attribute(
const Dwarf_Die *die,
6033 array_type_def::subrange_type::bound_value &value)
6038 if (!die_unsigned_constant_attribute(die, attr_name, l))
6040 value.set_unsigned(l);
6045 if (!die_signed_constant_attribute(die, attr_name, l))
6047 value.set_signed(l);
6062form_is_DW_FORM_strx(
unsigned form)
6066#if defined HAVE_DW_FORM_strx1 \
6067 && defined HAVE_DW_FORM_strx2 \
6068 && defined HAVE_DW_FORM_strx3 \
6069 && defined HAVE_DW_FORM_strx4
6070 if (form == DW_FORM_strx1
6071 || form == DW_FORM_strx2
6072 || form == DW_FORM_strx3
6073 ||form == DW_FORM_strx4)
6090form_is_DW_FORM_line_strp(
unsigned form)
6094#if defined HAVE_DW_FORM_line_strp
6095 if (form == DW_FORM_line_strp)
6122die_flag_attribute(
const Dwarf_Die* die,
6125 bool recursively =
true)
6127 Dwarf_Attribute attr;
6129 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6130 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6134 if (dwarf_formflag(&attr, &f))
6148die_linkage_name(
const Dwarf_Die* die)
6153 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6154 if (linkage_name.empty())
6155 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6156 return linkage_name;
6170die_decl_file_attribute(
const Dwarf_Die* die)
6175 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6177 return str ? str :
"";
6198die_die_attribute(
const Dwarf_Die* die,
6203 Dwarf_Attribute attr;
6205 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6206 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6209 return dwarf_formref_die(&attr, &result);
6239subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6241 Dwarf_Die& referenced_subrange)
6243 bool result =
false;
6245 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6248 Dwarf_Die referenced_die;
6249 if (die_die_attribute(die, attr_name, referenced_die))
6251 unsigned tag = dwarf_tag(&referenced_die);
6252 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6255 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6257 tag = dwarf_tag(&type_die);
6258 if (tag == DW_TAG_subrange_type)
6260 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6296subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6298 array_type_def::subrange_type::bound_value& v,
6301 bool result =
false;
6303 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6306 Dwarf_Die subrange_die;
6307 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6310 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6328die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6330 Dwarf_Attribute attr;
6331 if (!dwarf_attr_integrate(die, attr_name, &attr))
6333 return dwarf_formaddr(&attr, &result) == 0;
6344die_location(
const reader& rdr,
const Dwarf_Die* die)
6349 string file = die_decl_file_attribute(die);
6351 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6353 if (!file.empty() && line != 0)
6356 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6368die_name(
const Dwarf_Die* die)
6370 string name = die_string_attribute(die, DW_AT_name);
6386die_loc_and_name(
const reader& rdr,
6390 string& linkage_name)
6392 loc = die_location(rdr, die);
6393 name = die_name(die);
6394 linkage_name = die_linkage_name(die);
6407die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6412 uint64_t byte_size = 0, bit_size = 0;
6414 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6416 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6420 bit_size = byte_size * 8;
6443 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6450 case private_access:
6451 result = private_access;
6454 case protected_access:
6455 result = protected_access;
6459 result = public_access;
6478die_is_public_decl(
const Dwarf_Die* die)
6482 bool is_public =
false;
6488 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6489 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6490 die_flag_attribute(die, DW_AT_external, is_public);
6491 else if (tag == DW_TAG_namespace)
6493 string name = die_name(die);
6494 is_public = !name.empty();
6508die_is_effectively_public_decl(
const reader& rdr,
6509 const Dwarf_Die* die)
6511 if (die_is_public_decl(die))
6514 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6515 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6518 Dwarf_Die parent_die;
6519 size_t where_offset = 0;
6520 if (!get_parent_die(rdr, die, parent_die, where_offset))
6523 tag = dwarf_tag(&parent_die);
6524 if (tag == DW_TAG_compile_unit
6525 || tag == DW_TAG_partial_unit
6526 || tag == DW_TAG_type_unit)
6530 if (tag == DW_TAG_namespace)
6532 string name = die_name(&parent_die);
6551die_is_declaration_only(Dwarf_Die* die)
6553 bool is_declaration =
false;
6554 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6555 if (is_declaration && !die_has_size_attribute(die))
6566die_is_function_decl(
const Dwarf_Die *die)
6571 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6572 if (tag == DW_TAG_subprogram)
6583die_is_variable_decl(
const Dwarf_Die *die)
6588 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6589 if (tag == DW_TAG_variable)
6600die_has_size_attribute(
const Dwarf_Die *die)
6603 if (die_size_in_bits(die, s))
6614die_has_no_child(
const Dwarf_Die *die)
6620 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6633die_is_declaration_only(
const Dwarf_Die* die)
6634{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6642die_is_artificial(Dwarf_Die* die)
6645 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6652is_type_tag(
unsigned tag)
6654 bool result =
false;
6658 case DW_TAG_array_type:
6659 case DW_TAG_class_type:
6660 case DW_TAG_enumeration_type:
6661 case DW_TAG_pointer_type:
6662 case DW_TAG_reference_type:
6663 case DW_TAG_string_type:
6664 case DW_TAG_structure_type:
6665 case DW_TAG_subroutine_type:
6666 case DW_TAG_typedef:
6667 case DW_TAG_union_type:
6668 case DW_TAG_ptr_to_member_type:
6669 case DW_TAG_set_type:
6670 case DW_TAG_subrange_type:
6671 case DW_TAG_base_type:
6672 case DW_TAG_const_type:
6673 case DW_TAG_file_type:
6674 case DW_TAG_packed_type:
6675 case DW_TAG_thrown_type:
6676 case DW_TAG_volatile_type:
6677 case DW_TAG_restrict_type:
6678 case DW_TAG_interface_type:
6679 case DW_TAG_unspecified_type:
6680 case DW_TAG_shared_type:
6681 case DW_TAG_rvalue_reference_type:
6682 case DW_TAG_coarray_type:
6683 case DW_TAG_atomic_type:
6684 case DW_TAG_immutable_type:
6707is_canon_type_to_be_propagated_tag(
unsigned tag)
6709 bool result =
false;
6713 case DW_TAG_class_type:
6714 case DW_TAG_structure_type:
6715 case DW_TAG_union_type:
6716 case DW_TAG_subroutine_type:
6717 case DW_TAG_subprogram:
6738type_comparison_result_to_be_cached(
unsigned tag)
6743 case DW_TAG_class_type:
6744 case DW_TAG_structure_type:
6745 case DW_TAG_union_type:
6746 case DW_TAG_subroutine_type:
6747 case DW_TAG_subprogram:
6768maybe_cache_type_comparison_result(
const reader& rdr,
6773 if (!type_comparison_result_to_be_cached(tag)
6774 || (result != COMPARISON_RESULT_EQUAL
6775 && result != COMPARISON_RESULT_DIFFERENT))
6778 rdr.die_comparison_results_[p] = result;
6798get_cached_type_comparison_result(
const