libabigail
abg-corpus.cc
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright (C) 2013-2023 Red Hat, Inc.
5 
6 /// @file
7 
8 #include "config.h"
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <cstdio>
13 #include <cstring>
14 #include <stdexcept>
15 #include <unordered_map>
16 #include <set>
17 
18 #include "abg-internal.h"
19 
20 // <headers defining libabigail's API go under here>
21 ABG_BEGIN_EXPORT_DECLARATIONS
22 
23 #include "abg-corpus.h"
24 #include "abg-ir.h"
25 #include "abg-reader.h"
26 #include "abg-sptr-utils.h"
27 #include "abg-symtab-reader.h"
28 #include "abg-tools-utils.h"
29 #include "abg-writer.h"
30 
32 // </headers defining libabigail's API>
33 
34 #include "abg-corpus-priv.h"
35 #include "abg-ir-priv.h"
36 
37 namespace abigail
38 {
39 
40 namespace ir
41 {
42 
43 using std::ostringstream;
44 using std::unordered_map;
45 using std::list;
46 using std::vector;
47 
49 
50 /// Constructor of @ref corpus::exported_decls_builder.
51 ///
52 /// @param fns a reference to the vector of exported functions.
53 ///
54 /// @param vars a reference to the vector of exported variables.
55 ///
56 /// @param fns_suppress_regexps the regular expressions that designate
57 /// the functions to suppress from the exported functions set.
58 ///
59 /// @param vars_suppress_regexps the regular expressions that designate
60 /// the variables to suppress from the exported variables set.
61 ///
62 /// @param fns_keep_regexps the regular expressions that designate the
63 /// functions to keep in the exported functions set.
64 ///
65 /// @param fns_keep_regexps the regular expressions that designate the
66 /// functions to keep in the exported functions set.
67 ///
68 /// @param vars_keep_regexps the regular expressions that designate
69 /// the variables to keep in the exported variables set.
70 ///
71 /// @param sym_id_of_fns_to_keep the IDs of the functions to keep in
72 /// the exported functions set.
73 ///
74 /// @param sym_id_of_vars_to_keep the IDs of the variables to keep in
75 /// the exported variables set.
76 corpus::exported_decls_builder
77 ::exported_decls_builder(functions& fns,
78  variables& vars,
79  strings_type& fns_suppress_regexps,
80  strings_type& vars_suppress_regexps,
81  strings_type& fns_keep_regexps,
82  strings_type& vars_keep_regexps,
83  strings_type& sym_id_of_fns_to_keep,
84  strings_type& sym_id_of_vars_to_keep)
85  : priv_(new priv(fns, vars,
86  fns_suppress_regexps,
87  vars_suppress_regexps,
88  fns_keep_regexps,
89  vars_keep_regexps,
90  sym_id_of_fns_to_keep,
91  sym_id_of_vars_to_keep))
92 {
93 }
94 
95 /// Getter for the reference to the vector of exported functions.
96 /// This vector is shared with with the @ref corpus. It's where the
97 /// set of exported function is ultimately stored.
98 ///
99 /// @return a reference to the vector of exported functions.
100 const corpus::functions&
102 {return priv_->fns_;}
103 
104 /// Getter for the reference to the vector of exported functions.
105 /// This vector is shared with with the @ref corpus. It's where the
106 /// set of exported function is ultimately stored.
107 ///
108 /// @return a reference to the vector of exported functions.
111 {return priv_->fns_;}
112 
113 /// Test if a given function ID maps to several functions in the same corpus.
114 ///
115 /// The magic of ELF symbol aliases makes it possible for an ELF
116 /// symbol alias to designate several different functions. This
117 /// function tests if the ELF symbol of a given function has a aliases
118 /// that designates another function or not.
119 ///
120 /// @param fn the function to consider.
121 ///
122 /// @return the set of functions designated by the ELF symbol of @p
123 /// fn, or nullptr if the function ID maps to just @p fn.
124 std::unordered_set<function_decl*>*
126 {
127  std::unordered_set<function_decl*> *fns_for_id =
128  priv_->fn_id_is_in_id_fns_map(fn);
129  if (fns_for_id && fns_for_id->size() > 1)
130  return fns_for_id;
131 
132  return nullptr;
133 }
134 
135 /// Getter for the reference to the vector of exported variables.
136 /// This vector is shared with with the @ref corpus. It's where the
137 /// set of exported variable is ultimately stored.
138 ///
139 /// @return a reference to the vector of exported variables.
140 const corpus::variables&
142 {return priv_->vars_;}
143 
144 /// Getter for the reference to the vector of exported variables.
145 /// This vector is shared with with the @ref corpus. It's where the
146 /// set of exported variable is ultimately stored.
147 ///
148 /// @return a reference to the vector of exported variables.
151 {return priv_->vars_;}
152 
153 /// Consider at all the tunables that control wether a function should
154 /// be added to the set of exported function and if it fits in, add
155 /// the function to that set.
156 ///
157 /// @param fn the function to add the set of exported functions.
158 ///
159 /// @return true iff the function was added to the set of exported
160 /// functions.
161 bool
163 {
165  return false;
166 
167  const string& fn_id = priv_->get_id(*fn);
168  ABG_ASSERT(!fn_id.empty());
169 
170  if (priv_->fn_is_in_id_fns_map(fn))
171  return false;
172 
173  if (priv_->keep_wrt_id_of_fns_to_keep(fn)
174  && priv_->keep_wrt_regex_of_fns_to_suppress(fn)
175  && priv_->keep_wrt_regex_of_fns_to_keep(fn))
176  {
177  priv_->add_fn_to_exported(fn);
178  return true;
179  }
180  return false;
181 }
182 
183 /// Consider at all the tunables that control wether a variable should
184 /// be added to the set of exported variable and if it fits in, add
185 /// the variable to that set.
186 ///
187 /// @param fn the variable to add the set of exported variables.
188 ///
189 /// @return true iff the variable was added to the set of exported
190 /// variables.
191 bool
193 {
194  if (!var->get_is_in_public_symbol_table())
195  return false;
196 
197  const interned_string& var_id = priv_->get_id(*var);
198  ABG_ASSERT(!var_id.empty());
199 
200  if (priv_->var_id_is_in_id_var_map(var_id))
201  return false;
202 
203  if (priv_->keep_wrt_id_of_vars_to_keep(var)
204  && priv_->keep_wrt_regex_of_vars_to_suppress(var)
205  && priv_->keep_wrt_regex_of_vars_to_keep(var))
206  {
207  priv_->add_var_to_exported(var);
208  return true;
209  }
210  return false;
211 }
212 
213 // </corpus::exported_decls_builder>
214 
215 /// Convenience typedef for a hash map of pointer to function_decl and
216 /// boolean.
217 typedef unordered_map<const function_decl*,
218  bool,
221 
222 /// Convenience typedef for a hash map of string and pointer to
223 /// function_decl.
224 typedef unordered_map<string, const function_decl*> str_fn_ptr_map_type;
225 
226 /// Convenience typedef for a hash map of pointer to var_decl and boolean.
227 typedef unordered_map<const var_decl*,
228  bool,
231 
232 /// This is a comparison functor for comparing pointers to @ref
233 /// function_decl.
234 struct func_comp
235 {
236  /// The comparisong operator for pointers to @ref function_decl. It
237  /// performs a string comparison of the mangled names of the
238  /// functions. If the functions don't have mangled names, it
239  /// compares their names instead.
240  ///
241  /// @param first the first function to consider in the comparison.
242  ///
243  /// @param second the second function to consider in the comparison.
244  ///
245  /// @return true if the (mangled) name of the first function is less
246  /// than the (mangled)name of the second one, false otherwise.
247  bool
248  operator()(const function_decl* first,
249  const function_decl* second) const
250  {
251  ABG_ASSERT(first != 0 && second != 0);
252 
253  string first_name, second_name;
254  first_name = first->get_linkage_name();
255  if (first_name.empty())
256  first_name = first->get_name();
257  ABG_ASSERT(!first_name.empty());
258 
259  second_name = second->get_linkage_name();
260  if (second_name.empty())
261  second_name = second->get_name();
262  ABG_ASSERT(!second_name.empty());
263 
264  return first_name < second_name;
265  }
266 };
267 
268 /// This is a comparison functor for comparing pointers to @ref
269 /// var_decl.
270 struct var_comp
271 {
272  /// The comparison operator for pointers to @ref var_decl.
273  ///
274  /// It perform a string comparison on the names of the variables.
275  ///
276  /// @param first the first variable to consider for the comparison.
277  ///
278  /// @param second the second variable to consider for the comparison.
279  ///
280  /// @return true if first is less than second, false otherwise.
281  bool
282  operator()(const var_decl* first,
283  const var_decl* second) const
284  {
285  ABG_ASSERT(first != 0 && second != 0);
286 
287  string first_name, second_name;
288  first_name = first->get_linkage_name();
289  if (first_name.empty())
290  {
291  first_name = first->get_pretty_representation();
292  second_name = second->get_pretty_representation();
293  ABG_ASSERT(!second_name.empty());
294  }
295  ABG_ASSERT(!first_name.empty());
296 
297  if (second_name.empty())
298  second_name = second->get_linkage_name();
299 
300  if (second_name.empty())
301  {
302  second_name = second->get_pretty_representation();
303  first_name = first->get_pretty_representation();
304  ABG_ASSERT(!first_name.empty());
305  }
306  ABG_ASSERT(!second_name.empty());
307 
308  return first_name < second_name;
309  }
310 };
311 
312 
313 /// A comparison functor to compare elf_symbols for the purpose of
314 /// sorting.
315 struct comp_elf_symbols_functor
316 {
317  bool
318  operator()(const elf_symbol& l,
319  const elf_symbol& r) const
320  {return l.get_id_string() < r.get_id_string();}
321 
322  bool
323  operator()(const elf_symbol_sptr l,
324  const elf_symbol_sptr r) const
325  {return operator()(*l, *r);}
326 }; // end struct comp_elf_symbols_functor
327 
328 
329 // <corpus stuff>
330 
331 /// Get the maps that associate a name to a certain kind of type.
332 type_maps&
334 {return types_;}
335 
336 /// Get the maps that associate a name to a certain kind of type.
337 const type_maps&
339 {return types_;}
340 
341 /// Return a sorted vector of function symbols for this corpus.
342 ///
343 /// Note that the first time this function is called, the symbols are
344 /// sorted and cached. Subsequent invocations of this function return
345 /// the cached vector that was built previously.
346 ///
347 /// @return the sorted list of function symbols.
348 const elf_symbols&
350 {
351  if (!sorted_fun_symbols)
352  {
353  if (symtab_)
354  {
355  auto filter = symtab_->make_filter();
356  filter.set_functions();
357  sorted_fun_symbols = elf_symbols(symtab_->begin(filter),
358  symtab_->end());
359  }
360  else
361  sorted_fun_symbols = elf_symbols();
362  }
363  return *sorted_fun_symbols;
364 }
365 
366 /// Return a map from name to function symbol for this corpus.
367 ///
368 /// Note that the first time this function is called, the map is built.
369 /// Subsequent invocations of this function return the cached map that was
370 /// built previously.
371 ///
372 /// @return the name function symbol map
375 {
376  if (!fun_symbol_map)
377  {
378  fun_symbol_map = string_elf_symbols_map_type();
379  for (const auto& symbol : get_sorted_fun_symbols())
380  (*fun_symbol_map)[symbol->get_name()].push_back(symbol);
381  }
382  return *fun_symbol_map;
383 }
384 
385 /// Getter for a sorted vector of the function symbols undefined in
386 /// this corpus.
387 ///
388 /// @return a vector of the function symbols undefined in this corpus,
389 /// sorted by name and then version.
390 const elf_symbols&
392 {
393  if (!sorted_undefined_fun_symbols)
394  {
395  if (symtab_)
396  {
397  auto filter = symtab_->make_filter();
398  filter.set_functions();
399  filter.set_undefined_symbols();
400  filter.set_public_symbols(false);
401 
402  sorted_undefined_fun_symbols =
403  elf_symbols(symtab_->begin(filter), symtab_->end());
404  }
405  else
406  sorted_undefined_fun_symbols = elf_symbols();
407  }
408  return *sorted_undefined_fun_symbols;
409 }
410 
411 /// Return a map from name to undefined function symbol for this corpus.
412 ///
413 /// Note that the first time this function is called, the map is built.
414 /// Subsequent invocations of this function return the cached map that was
415 /// built previously.
416 ///
417 /// @return the name function symbol map for undefined symbols
420 {
421  if (!undefined_fun_symbol_map)
422  {
423  undefined_fun_symbol_map = string_elf_symbols_map_type();
424  for (const auto& symbol : get_sorted_undefined_fun_symbols())
425  (*undefined_fun_symbol_map)[symbol->get_name()].push_back(symbol);
426  }
427  return *undefined_fun_symbol_map;
428 }
429 
430 /// Return a list of symbols that are not referenced by any function of
431 /// corpus::get_functions().
432 ///
433 /// Note that this function considers the list of function symbols to keep,
434 /// that is provided by corpus::get_sym_ids_of_fns_to_keep(). If a given
435 /// unreferenced function symbol is not in the list of functions to keep, then
436 /// that symbol is dropped and will not be part of the resulting table of
437 /// unreferenced symbol that is built.
438 ///
439 /// @return list of symbols that are not referenced by any function
440 const elf_symbols&
442 {
443  if (!unrefed_fun_symbols)
444  {
445  unrefed_fun_symbols = elf_symbols();
446  if (symtab_)
447  {
448  unordered_map<string, bool> refed_funs;
449 
450  for (const auto& function : fns)
451  if (elf_symbol_sptr sym = function->get_symbol())
452  {
453  refed_funs[sym->get_id_string()] = true;
454  for (elf_symbol_sptr a = sym->get_next_alias();
455  a && !a->is_main_symbol(); a = a->get_next_alias())
456  refed_funs[a->get_id_string()] = true;
457  }
458 
459  auto filter = symtab_->make_filter();
460  filter.set_functions();
461  for (const auto& symbol :
462  symtab_reader::filtered_symtab(*symtab_, filter))
463  {
464  const std::string sym_id = symbol->get_id_string();
465  if (refed_funs.find(sym_id) == refed_funs.end())
466  {
467  bool keep = sym_id_fns_to_keep.empty();
468  for (const auto& id : sym_id_fns_to_keep)
469  {
470  if (id == sym_id)
471  {
472  keep = true;
473  break;
474  }
475  }
476  if (keep)
477  unrefed_fun_symbols->push_back(symbol);
478  }
479  }
480  }
481  }
482  return *unrefed_fun_symbols;
483 }
484 
485 /// Getter for the sorted vector of variable symbols for this corpus.
486 ///
487 /// Note that the first time this function is called, it computes the
488 /// sorted vector, caches the result and returns it. Subsequent
489 /// invocations of this function just return the cached vector.
490 ///
491 /// @return the sorted vector of variable symbols for this corpus.
492 const elf_symbols&
494 {
495  if (!sorted_var_symbols)
496  {
497  if (symtab_)
498  {
499  auto filter = symtab_->make_filter();
500  filter.set_variables();
501 
502  sorted_var_symbols = elf_symbols(symtab_->begin(filter),
503  symtab_->end());
504  }
505  else
506  sorted_var_symbols = elf_symbols();
507  }
508  return *sorted_var_symbols;
509 }
510 
511 /// Return a map from name to variable symbol for this corpus.
512 ///
513 /// Note that the first time this function is called, the map is built.
514 /// Subsequent invocations of this function return the cached map that was
515 /// built previously.
516 ///
517 /// @return the name variable symbol map
520 {
521  if (!var_symbol_map)
522  {
523  var_symbol_map = string_elf_symbols_map_type();
524  for (const auto& symbol : get_sorted_var_symbols())
525  (*var_symbol_map)[symbol->get_name()].push_back(symbol);
526  }
527  return *var_symbol_map;
528 }
529 
530 /// Getter for a sorted vector of the variable symbols undefined in
531 /// this corpus.
532 ///
533 /// @return a vector of the variable symbols undefined in this corpus,
534 /// sorted by name and then version.
535 const elf_symbols&
537 {
538  if (!sorted_undefined_var_symbols)
539  {
540  if (symtab_)
541  {
542  auto filter = symtab_->make_filter();
543  filter.set_variables();
544  filter.set_undefined_symbols();
545  filter.set_public_symbols(false);
546 
547  sorted_undefined_var_symbols =
548  elf_symbols(symtab_->begin(filter), symtab_->end());
549  }
550  else
551  sorted_undefined_var_symbols = elf_symbols();
552  }
553  return *sorted_undefined_var_symbols;
554 }
555 
556 /// Return a map from name to undefined variable symbol for this corpus.
557 ///
558 /// Note that the first time this function is called, the map is built.
559 /// Subsequent invocations of this function return the cached map that was
560 /// built previously.
561 ///
562 /// @return the name undefined variable symbol map
565 {
566  if (!undefined_var_symbol_map)
567  {
568  undefined_var_symbol_map = string_elf_symbols_map_type();
569  for (const auto& symbol : get_sorted_undefined_var_symbols())
570  (*undefined_var_symbol_map)[symbol->get_name()].push_back(symbol);
571  }
572  return *undefined_var_symbol_map;
573 }
574 
575 /// Return a list of symbols that are not referenced by any variable of
576 /// corpus::get_variables().
577 ///
578 /// Note that this function considers the list of variable symbols to keep,
579 /// that is provided by corpus::get_sym_ids_of_vars_to_keep(). If a given
580 /// unreferenced variable symbol is not in the list of variable to keep, then
581 /// that symbol is dropped and will not be part of the resulting table of
582 /// unreferenced symbol that is built.
583 ///
584 /// @return list of symbols that are not referenced by any variable
585 const elf_symbols&
587 {
588  if (!unrefed_var_symbols)
589  {
590  unrefed_var_symbols = elf_symbols();
591  if (symtab_)
592  {
593  unordered_map<string, bool> refed_vars;
594  for (const auto& variable : vars)
595  if (elf_symbol_sptr sym = variable->get_symbol())
596  {
597  refed_vars[sym->get_id_string()] = true;
598  for (elf_symbol_sptr a = sym->get_next_alias();
599  a && !a->is_main_symbol(); a = a->get_next_alias())
600  refed_vars[a->get_id_string()] = true;
601  }
602 
603  auto filter = symtab_->make_filter();
604  filter.set_variables();
605  for (const auto& symbol :
606  symtab_reader::filtered_symtab(*symtab_, filter))
607  {
608  const std::string sym_id = symbol->get_id_string();
609  if (refed_vars.find(sym_id) == refed_vars.end())
610  {
611  bool keep = sym_id_vars_to_keep.empty();
612  for (const auto& id : sym_id_vars_to_keep)
613  {
614  if (id == sym_id)
615  {
616  keep = true;
617  break;
618  }
619  }
620  if (keep)
621  unrefed_var_symbols->push_back(symbol);
622  }
623  }
624  }
625  }
626  return *unrefed_var_symbols;
627 }
628 
629 
630 /// Getter of the set of pretty representation of types that are
631 /// reachable from public interfaces (global functions and variables).
632 ///
633 /// @return the set of pretty representation of types that are
634 /// reachable from public interfaces (global functions and variables).
635 unordered_set<interned_string, hash_interned_string>*
637 {
638  if (group)
639  return group->get_public_types_pretty_representations();
640 
641  if (pub_type_pretty_reprs_ == 0)
642  pub_type_pretty_reprs_ =
643  new unordered_set<interned_string, hash_interned_string>;
644  return pub_type_pretty_reprs_;
645 }
646 
647 /// Lookup the function which has a given function ID.
648 ///
649 /// Note that there can have been several functions with the same ID.
650 /// This is because debug info can declare the same function in
651 /// several different translation units. Normally, all these function
652 /// should be equal. But still, this function returns all these
653 /// functions.
654 ///
655 /// @param id the ID of the function to lookup. This ID must be
656 /// either the result of invoking function::get_id() of
657 /// elf_symbol::get_id_string().
658 ///
659 /// @return the set of functions which ID is @p id, or nil if no
660 /// function with that ID was found.
661 std::unordered_set<function_decl*>*
663 {
665  if (b)
666  {
667  auto i = b->priv_->id_fns_map_.find(id);
668  if (i == b->priv_->id_fns_map_.end())
669  return 0;
670  return &i->second;
671  }
672  return nullptr;
673 }
674 
675 /// Destructor of the @ref corpus::priv type.
677 {
678  delete pub_type_pretty_reprs_;
679 }
680 
681 /// Constructor of the @ref corpus type.
682 ///
683 /// @param env the environment of the corpus.
684 ///
685 /// @param path the path to the file containing the ABI corpus.
686 corpus::corpus(const ir::environment& env, const string& path)
687 {
688  priv_.reset(new priv(path, env));
689  init_format_version();
690 }
691 
692 corpus::~corpus() = default;
693 
694 /// Getter of the enviroment of the corpus.
695 ///
696 /// @return the environment of this corpus.
697 const environment&
699 {return priv_->env;}
700 
701 /// Test if logging was requested.
702 ///
703 /// @return true iff logging was requested.
704 bool
706 {return priv_->do_log;}
707 
708 /// Request logging, or not.
709 ///
710 /// @param f true iff logging is requested.
711 void
713 {priv_->do_log = f;}
714 
715 /// Add a translation unit to the current ABI Corpus.
716 ///
717 /// Note that two translation units with the same path (as returned by
718 /// translation_unit::get_path) cannot be added to the same @ref
719 /// corpus. If that happens, the library aborts.
720 ///
721 /// @param tu the new translation unit to add.
722 void
724 {
725  ABG_ASSERT(priv_->members.insert(tu).second);
726 
727  if (!tu->get_absolute_path().empty())
728  {
729  // Update the path -> translation_unit map.
730  string_tu_map_type::const_iterator i =
731  priv_->path_tu_map.find(tu->get_absolute_path());
732  ABG_ASSERT(i == priv_->path_tu_map.end());
733  priv_->path_tu_map[tu->get_absolute_path()] = tu;
734  }
735 
736  tu->set_corpus(this);
737 }
738 
739 /// Return the list of translation units of the current corpus.
740 ///
741 /// @return the list of translation units of the current corpus.
742 const translation_units&
744 {return priv_->members;}
745 
746 /// Find the translation unit that has a given path.
747 ///
748 /// @param path the path of the translation unit to look for.
749 ///
750 /// @return the translation unit found, if any. Otherwise, return
751 /// nil.
753 corpus::find_translation_unit(const string &path) const
754 {
755  string_tu_map_type::const_iterator i =
756  priv_->path_tu_map.find(path);
757 
758  if (i == priv_->path_tu_map.end())
759  return translation_unit_sptr();
760  return i->second;
761 }
762 
763 /// Erase the translation units contained in this in-memory object.
764 ///
765 /// Note that the on-disk archive file that contains the serialized
766 /// representation of this object is not modified.
767 void
769 {priv_->members.clear();}
770 
771 /// Get the maps that associate a name to a certain kind of type.
772 ///
773 /// @return the maps that associate a name to a certain kind of type.
774 type_maps&
776 {return priv_->types_;}
777 
778 /// Get the maps that associate a name to a certain kind of type.
779 ///
780 /// @return the maps that associate a name to a certain kind of
781 /// type.
782 const type_maps&
784 {return priv_->types_;}
785 
786 /// Get the maps that associate a location string to a certain kind of
787 /// type.
788 ///
789 /// The location string is the result of the invocation to the
790 /// function abigail::ir::location::expand(). It has the form
791 /// "file.c:4:1", with 'file.c' being the file name, '4' being the
792 /// line number and '1' being the column number.
793 ///
794 /// @return the maps.
795 const type_maps&
797 {return priv_->type_per_loc_map_;}
798 
799 /// Test if the recording of reachable types (and thus, indirectly,
800 /// the recording of non-reachable types) is activated for the
801 /// current @ref corpus.
802 ///
803 /// @return true iff the recording of reachable types is activated for
804 /// the current @ref corpus.
805 bool
807 {
808  return (priv_->get_public_types_pretty_representations()
809  && !priv_->get_public_types_pretty_representations()->empty());
810 }
811 
812 /// Record a type as being reachable from public interfaces (global
813 /// functions and variables).
814 ///
815 /// @param t the type to record as reachable.
816 void
818 {
819  string repr = get_pretty_representation(&t, /*internal=*/false);
820  interned_string s = t.get_environment().intern(repr);
821  priv_->get_public_types_pretty_representations()->insert(s);
822 }
823 
824 /// Test if a type is reachable from public interfaces (global
825 /// functions and variables).
826 ///
827 /// For a type to be considered reachable from public interfaces, it
828 /// must have been previously marked as such by calling
829 /// corpus::record_type_as_reachable_from_public_interfaces.
830 ///
831 /// @param t the type to test for.
832 ///
833 /// @return true iff @p t is reachable from public interfaces.
834 bool
836 {
837  string repr = get_pretty_representation(&t, /*internal=*/false);
838  interned_string s = t.get_environment().intern(repr);
839 
840  return (priv_->get_public_types_pretty_representations()->find(s)
841  != priv_->get_public_types_pretty_representations()->end());
842 }
843 
844 /// Getter of a sorted vector of the types that are *NOT* reachable
845 /// from public interfaces.
846 ///
847 /// Note that for this to be non-empty, the libabigail reader that
848 /// analyzed the input (be it a binary or an abixml file) must have be
849 /// configured to load types that are not reachable from public
850 /// interfaces.
851 ///
852 /// @return a reference to a vector of sorted types NON reachable from
853 /// public interfaces.
854 const vector<type_base_wptr>&
856 {
857  if (priv_->types_not_reachable_from_pub_ifaces_.empty())
858  {
859  const type_maps& types = get_types();
860  for (vector<type_base_wptr>::const_iterator it =
861  types.get_types_sorted_by_name().begin();
862  it != types.get_types_sorted_by_name().end();
863  ++it)
864  {
865  type_base_sptr t(*it);
867  priv_->types_not_reachable_from_pub_ifaces_.push_back(t);
868  }
869  }
870 
871  return priv_->types_not_reachable_from_pub_ifaces_;
872 }
873 
874 /// Get the maps that associate a location string to a certain kind of
875 /// type.
876 ///
877 /// The location string is the result of the invocation to the
878 /// function abigail::ir::location::expand(). It has the form
879 /// "file.c:4:1", with 'file.c' being the file name, '4' being the
880 /// line number and '1' being the column number.
881 ///
882 /// @return the maps.
883 type_maps&
885 {return priv_->type_per_loc_map_;}
886 
887 /// Getter of the group this corpus is a member of.
888 ///
889 /// @return the group this corpus is a member of, or nil if it's not
890 /// part of any @ref corpus_group.
891 const corpus_group*
893 {return priv_->group;}
894 
895 /// Getter of the group this corpus belongs to.
896 ///
897 /// @return the group this corpus belong to, or nil if it's not part
898 /// of any @ref corpus_group.
901 {return priv_->group;}
902 
903 /// Setter of the group this corpus belongs to.
904 ///
905 /// @param g the new group.
906 void
907 corpus::set_group(corpus_group* g)
908 {priv_->group = g;}
909 
910 /// Initialize the abixml serialization format version number of the
911 /// corpus.
912 ///
913 /// This function sets the format version number ot the default one
914 /// supported by the current version of Libabigail.
915 void
916 corpus::init_format_version()
917 {
919  (priv_->env.get_config().get_format_major_version_number());
921  (priv_->env.get_config().get_format_minor_version_number());
922 }
923 
924 /// Getter for the origin of the corpus.
925 ///
926 /// @return the origin of the corpus.
929 {return priv_->origin_;}
930 
931 /// Setter for the origin of the corpus.
932 ///
933 /// @param o the new origin for the corpus.
934 void
936 {priv_->origin_ = o;}
937 
938 /// Getter of the major version number of the abixml serialization
939 /// format.
940 ///
941 /// @return the major version number of the abixml format.
942 string&
944 {return priv_->format_major_version_number_;}
945 
946 /// Setter of the major version number of the abixml serialization
947 /// format.
948 ///
949 /// @param maj the new major version numberof the abixml format.
950 void
952 {priv_->format_major_version_number_ = maj;}
953 
954 /// Getter of the minor version number of the abixml serialization
955 /// format.
956 ///
957 /// @return the minor version number of the abixml serialization
958 /// format.
959 string&
961 {return priv_->format_minor_version_number_;}
962 
963 /// Setter of the minor version number of the abixml serialization
964 /// format.
965 ///
966 /// @param min the new minor version number of the abixml
967 /// serialization format.
968 void
970 {priv_->format_minor_version_number_ = min;}
971 
972 /// Get the file path associated to the corpus file.
973 ///
974 /// A subsequent call to corpus::read will deserialize the content of
975 /// the abi file expected at this path; likewise, a call to
976 /// corpus::write will serialize the translation units contained in
977 /// the corpus object into the on-disk file at this path.
978 ///
979 /// @return the file path associated to the current corpus.
980 string&
982 {return priv_->path;}
983 
984 /// Set the file path associated to the corpus file.
985 ///
986 /// A subsequent call to corpus::read will deserialize the content of
987 /// the abi file expected at this path; likewise, a call to
988 /// corpus::write will serialize the translation units contained in
989 /// the corpus object into the on-disk file at this path.
990 ///
991 /// @param path the new file path to assciate to the current corpus.
992 void
993 corpus::set_path(const string& path)
994 {priv_->path = path;}
995 
996 /// Getter of the needed property of the corpus.
997 ///
998 /// This property is meaningful for, e.g, corpora built from ELF
999 /// shared library files. In that case, this is a vector of names of
1000 /// dependencies of the ELF shared library file.
1001 ///
1002 /// @return the vector of dependencies needed by this corpus.
1003 const vector<string>&
1005 {return priv_->needed;}
1006 
1007 /// Setter of the needed property of the corpus.
1008 ///
1009 /// This property is meaningful for, e.g, corpora built from ELF
1010 /// shared library files. In that case, this is a vector of names of
1011 /// dependencies of the ELF shared library file.
1012 ///
1013 /// @param needed the new vector of dependencies needed by this
1014 /// corpus.
1015 void
1016 corpus::set_needed(const vector<string>& needed)
1017 {priv_->needed = needed;}
1018 
1019 /// Getter for the soname property of the corpus.
1020 ///
1021 /// This property is meaningful for, e.g, corpora built from ELF
1022 /// shared library files. In that case, this is the shared object
1023 /// name exported by the shared library.
1024 ///
1025 /// @return the soname property of the corpus.
1026 const string&
1028 {return priv_->soname;}
1029 
1030 /// Setter for the soname property of the corpus.
1031 ///
1032 /// This property is meaningful for, e.g, corpora built from ELF
1033 /// shared library files. In that case, this is the shared object
1034 /// name exported by the shared library.
1035 ///
1036 /// @param soname the new soname property of the corpus.
1037 void
1038 corpus::set_soname(const string& soname)
1039 {priv_->soname = soname;}
1040 
1041 /// Getter for the architecture name of the corpus.
1042 ///
1043 /// This property is meaningful for e.g, corpora built from ELF shared
1044 /// library files. In that case, this is a string representation of
1045 /// the Elf{32,64}_Ehdr::e_machine field.
1046 ///
1047 /// @return the architecture name string.
1048 const string&
1050 {return priv_->architecture_name;}
1051 
1052 /// Setter for the architecture name of the corpus.
1053 ///
1054 /// This property is meaningful for e.g, corpora built from ELF shared
1055 /// library files. In that case, this is a string representation of
1056 /// the Elf{32,64}_Ehdr::e_machine field.
1057 ///
1058 /// @param arch the architecture name string.
1059 void
1061 {priv_->architecture_name = arch;}
1062 
1063 /// Tests if the corpus is empty from an ABI surface perspective. I.e. if all
1064 /// of these criteria are true:
1065 /// - all translation units (members) are empty
1066 /// - the maps function and variable symbols are not having entries
1067 /// - for shared libraries:
1068 /// - the soname is empty
1069 /// - there are no DT_NEEDED entries
1070 ///
1071 /// @return true if the corpus contains no translation unit.
1072 bool
1074 {
1075  bool members_empty = true;
1076  for (translation_units::const_iterator i = priv_->members.begin(),
1077  e = priv_->members.end();
1078  i != e; ++i)
1079  {
1080  if (!(*i)->is_empty())
1081  {
1082  members_empty = false;
1083  break;
1084  }
1085  }
1086  return (members_empty
1087  && (!get_symtab() || !get_symtab()->has_symbols())
1088  && priv_->soname.empty()
1089  && priv_->needed.empty()
1090  && priv_->architecture_name.empty()
1091  && !priv_->group);
1092 }
1093 
1094 /// Compare the current @ref corpus against another one.
1095 ///
1096 /// @param other the other corpus to compare against.
1097 ///
1098 /// @return true if the two corpus are equal, false otherwise.
1099 bool
1100 corpus::operator==(const corpus& other) const
1101 {
1102  translation_units::const_iterator i, j;
1103  for (i = get_translation_units().begin(),
1104  j = other.get_translation_units().begin();
1105  (i != get_translation_units().end()
1106  && j != other.get_translation_units().end());
1107  ++i, ++j)
1108  if ((**i) != (**j))
1109  return false;
1110 
1111  return (i == get_translation_units().end()
1112  && j == other.get_translation_units().end());
1113 }
1114 
1115 /// Setter for the symtab object.
1116 ///
1117 /// @param symtab a shared pointer to the new symtab object
1118 void
1119 corpus::set_symtab(symtab_reader::symtab_sptr symtab)
1120 {priv_->symtab_ = symtab;}
1121 
1122 /// Getter for the symtab object.
1123 ///
1124 /// @return a shared pointer to the symtab object
1125 const symtab_reader::symtab_sptr&
1127 {return priv_->symtab_;}
1128 
1129 /// Getter for the function symbols map.
1130 ///
1131 /// @return a reference to the function symbols map.
1134 {return priv_->get_fun_symbol_map();}
1135 
1136 /// Getter for the map of function symbols that are undefined in this
1137 /// corpus.
1138 ///
1139 /// @return the map of function symbols not defined in this corpus.
1140 /// The key of the map is the name of the function symbol. The value
1141 /// is a vector of all the function symbols that have the same name.
1144 {return priv_->get_undefined_fun_symbol_map();}
1145 
1146 /// Return a sorted vector of function symbols for this corpus.
1147 ///
1148 /// Note that the first time this function is called, the symbols are
1149 /// sorted and cached. Subsequent invocations of this function return
1150 /// the cached vector that was built previously.
1151 ///
1152 /// @return the sorted list of function symbols.
1153 const elf_symbols&
1155 {return priv_->get_sorted_fun_symbols();}
1156 
1157 /// Getter for a sorted vector of the function symbols undefined in
1158 /// this corpus.
1159 ///
1160 /// @return a vector of the function symbols undefined in this corpus,
1161 /// sorted by name and then version.
1162 const elf_symbols&
1164 {return priv_->get_sorted_undefined_fun_symbols();}
1165 
1166 /// Getter for the sorted vector of variable symbols for this corpus.
1167 ///
1168 /// Note that the first time this function is called, it computes the
1169 /// sorted vector, caches the result and returns it. Subsequent
1170 /// invocations of this function just return the cached vector.
1171 ///
1172 /// @return the sorted vector of variable symbols for this corpus.
1173 const elf_symbols&
1175 {return priv_->get_sorted_var_symbols();}
1176 
1177 /// Getter for a sorted vector of the variable symbols undefined in
1178 /// this corpus.
1179 ///
1180 /// @return a vector of the variable symbols undefined in this corpus,
1181 /// sorted by name and then version.
1182 const elf_symbols&
1184 {return priv_->get_sorted_undefined_var_symbols();}
1185 
1186 /// Getter for the variable symbols map.
1187 ///
1188 /// @return a reference to the variabl symbols map.
1191 {return priv_->get_var_symbol_map();}
1192 
1193 /// Getter for the map of variable symbols that are undefined in this
1194 /// corpus.
1195 ///
1196 /// @return the map of variable symbols not defined in this corpus.
1197 /// The key of the map is the name of the variable symbol. The value
1198 /// is a vector of all the variable symbols that have the same name.
1201 {return priv_->get_undefined_var_symbol_map();}
1202 
1203 /// Look in the function symbols map for a symbol with a given name.
1204 ///
1205 /// @param n the name of the symbol to look for.
1206 ///
1207 /// return the first symbol with the name @p n.
1208 const elf_symbol_sptr
1209 corpus::lookup_function_symbol(const string& n) const
1210 {
1211  if (get_fun_symbol_map().empty() && get_undefined_fun_symbol_map().empty())
1212  return elf_symbol_sptr();
1213 
1214  string_elf_symbols_map_type::const_iterator it = get_fun_symbol_map().find(n);
1215  if ( it == get_fun_symbol_map().end())
1216  {
1217  it = get_undefined_fun_symbol_map().find(n);
1218  if (it == get_undefined_fun_symbol_map().end())
1219  return elf_symbol_sptr();
1220  }
1221  return it->second[0];
1222 }
1223 
1224 /// Look into a set of symbols and look for a symbol that has a given
1225 /// version.
1226 ///
1227 /// This is a sub-routine for corpus::lookup_function_symbol() and
1228 /// corpus::lookup_variable_symbol().
1229 ///
1230 /// @param version the version of the symbol to look for.
1231 ///
1232 /// @param symbols the set of symbols to consider.
1233 ///
1234 /// @return the symbol found, or nil if none was found.
1235 static const elf_symbol_sptr
1236 find_symbol_by_version(const elf_symbol::version& version,
1237  const vector<elf_symbol_sptr>& symbols)
1238 {
1239  if (version.is_empty())
1240  {
1241  // We are looing for a symbol with no version.
1242 
1243  // So first look for possible aliases with no version
1244  for (elf_symbols::const_iterator s = symbols.begin();
1245  s != symbols.end();
1246  ++s)
1247  if ((*s)->get_version().is_empty())
1248  return *s;
1249 
1250  // Or, look for a version that is a default one!
1251  for (elf_symbols::const_iterator s = symbols.begin();
1252  s != symbols.end();
1253  ++s)
1254  if ((*s)->get_version().is_default())
1255  return *s;
1256  }
1257  else
1258  // We are looking for a symbol with a particular defined version.
1259  for (elf_symbols::const_iterator s = symbols.begin();
1260  s != symbols.end();
1261  ++s)
1262  if ((*s)->get_version().str() == version.str())
1263  return *s;
1264 
1265  return elf_symbol_sptr();
1266 }
1267 
1268 /// Look in the function symbols map for a symbol with a given name.
1269 ///
1270 /// @param symbol_name the name of the symbol to look for.
1271 ///
1272 /// @param version the version of the symbol to look for.
1273 ///
1274 /// return the symbol with name @p symbol_name and with version @p
1275 /// version, or nil if no symbol has been found with that name and
1276 /// version.
1277 const elf_symbol_sptr
1278 corpus::lookup_function_symbol(const string& symbol_name,
1279  const elf_symbol::version& version) const
1280 {
1281  if (get_fun_symbol_map().empty() && get_undefined_fun_symbol_map().empty())
1282  return elf_symbol_sptr();
1283 
1284  string_elf_symbols_map_type::const_iterator it =
1285  get_fun_symbol_map().find(symbol_name);
1286  if ( it == get_fun_symbol_map().end())
1287  {
1288  it = get_undefined_fun_symbol_map().find(symbol_name);
1289  if (it == get_undefined_fun_symbol_map().end())
1290  return elf_symbol_sptr();
1291  }
1292 
1293  return find_symbol_by_version(version, it->second);
1294 }
1295 
1296 /// Look in the function symbols map for a symbol with the same name
1297 /// and version as a given symbol.
1298 ///
1299 /// @param symbol the symbol to look for.
1300 ///
1301 /// return the symbol with the same name and version as @p symbol.
1302 const elf_symbol_sptr
1304 {return lookup_function_symbol(symbol.get_name(), symbol.get_version());}
1305 
1306 /// Look in the variable symbols map for a symbol with a given name.
1307 ///
1308 /// @param n the name of the symbol to look for.
1309 ///
1310 /// return the first symbol with the name @p n.
1311 const elf_symbol_sptr
1312 corpus::lookup_variable_symbol(const string& n) const
1313 {
1314  if (get_var_symbol_map().empty() && get_undefined_var_symbol_map().empty())
1315  return elf_symbol_sptr();
1316 
1317  string_elf_symbols_map_type::const_iterator it = get_var_symbol_map().find(n);
1318  if ( it == get_var_symbol_map().end())
1319  {
1320  it = get_undefined_var_symbol_map().find(n);
1321  if (it == get_undefined_var_symbol_map().end())
1322  return elf_symbol_sptr();
1323  }
1324  return it->second[0];
1325 }
1326 
1327 /// Look in the variable symbols map for a symbol with a given name.
1328 ///
1329 /// @param symbol_name the name of the symbol to look for.
1330 ///
1331 /// @param symbol_version the version of the symbol to look for.
1332 ///
1333 /// return the first symbol with the name @p symbol_name and with
1334 /// version @p version.
1335 const elf_symbol_sptr
1336 corpus::lookup_variable_symbol(const string& symbol_name,
1337  const elf_symbol::version& version) const
1338 {
1339  if (get_var_symbol_map().empty() && get_undefined_var_symbol_map().empty())
1340  return elf_symbol_sptr();
1341 
1342  string_elf_symbols_map_type::const_iterator it =
1343  get_var_symbol_map().find(symbol_name);
1344  if ( it == get_var_symbol_map().end())
1345  {
1346  it = get_undefined_var_symbol_map().find(symbol_name);
1347  if (it == get_undefined_var_symbol_map().end())
1348  return elf_symbol_sptr();
1349  }
1350 
1351  return find_symbol_by_version(version, it->second);
1352 }
1353 
1354 /// Look in the variable symbols map for a symbol with the same name
1355 /// and version as a given symbol.
1356 ///
1357 /// @param symbol the symbol to look for.
1358 ///
1359 /// return the symbol with the same name and version as @p symbol.
1360 const elf_symbol_sptr
1362 {return lookup_variable_symbol(symbol.get_name(), symbol.get_version());}
1363 
1364 /// Return the functions public decl table of the current corpus.
1365 ///
1366 /// The function public decl tables is a vector of all the functions
1367 /// and member functions found in the current corpus.
1368 ///
1369 /// Note that the caller can suppress some functions from the vector
1370 /// supplying regular expressions describing the set of functions she
1371 /// want to see removed from the public decl table by populating the
1372 /// vector of regular expressions returned by
1373 /// corpus::get_regex_patterns_of_fns_to_suppress().
1374 ///
1375 /// @return the vector of functions of the public decl table. The
1376 /// functions are sorted using their mangled name or name if they
1377 /// don't have mangle names.
1378 const corpus::functions&
1380 {return priv_->fns;}
1381 
1382 /// Lookup the function which has a given function ID.
1383 ///
1384 /// Note that there can have been several functions with the same ID.
1385 /// This is because debug info can declare the same function in
1386 /// several different translation units. Normally, all these function
1387 /// should be equal. But still, this function returns all these
1388 /// functions.
1389 ///
1390 /// @param id the ID of the function to lookup. This ID must be
1391 /// either the result of invoking function::get_id() of
1392 /// elf_symbol::get_id_string().
1393 ///
1394 /// @return the set of functions which ID is @p id, or nil if no
1395 /// function with that ID was found.
1396 const std::unordered_set<function_decl*>*
1398 {return priv_->lookup_functions(id);}
1399 
1400 const std::unordered_set<function_decl*>*
1401 corpus::lookup_functions(const char* id) const
1402 {
1403  if (!id)
1404  return nullptr;
1405 
1406  interned_string string_id = priv_->env.intern(id);
1407  return lookup_functions(string_id);
1408 }
1409 
1410 /// Lookup the exported variable which has a given variable ID.
1411 ///
1412 /// @param id the ID of the variable to look up.
1413 ///
1414 /// @return the variable with ID @p id that was found or nil if none
1415 /// was found.
1416 const var_decl*
1418 {
1420  auto i = b->priv_->id_var_map_.find(id);
1421  if (i == b->priv_->id_var_map_.end())
1422  return nullptr;
1423  return i->second;
1424 }
1425 
1426 /// Sort the set of functions exported by this corpus.
1427 ///
1428 /// Normally, you shouldn't be calling this as the code that creates
1429 /// the corpus for you should do it for you too.
1430 void
1432 {
1433  func_comp fc;
1434  std::sort(priv_->fns.begin(), priv_->fns.end(), fc);
1435 
1436  priv_->sorted_undefined_fns.clear();
1437 
1438  for (auto& f : priv_->undefined_fns)
1439  priv_->sorted_undefined_fns.push_back(f);
1440 
1441  std::sort(priv_->sorted_undefined_fns.begin(),
1442  priv_->sorted_undefined_fns.end(), fc);
1443 }
1444 
1445 /// Return the public decl table of the global variables of the
1446 /// current corpus.
1447 ///
1448 /// The variable public decls table is a vector of all the public
1449 /// global variables and static member variables found in the current
1450 /// corpus.
1451 ///
1452 /// Note that the caller can suppress some variables from the vector
1453 /// supplying regular expressions describing the set of variables she
1454 /// wants to see removed from the public decl table by populating the
1455 /// vector of regular expressions returned by
1456 /// corpus::get_regex_patterns_of_fns_to_suppress().
1457 ///
1458 /// @return the vector of variables of the public decl table. The
1459 /// variables are sorted using their name.
1460 const corpus::variables&
1462 {return priv_->vars;}
1463 
1464 /// Sort the set of variables exported by this corpus.
1465 ///
1466 /// Normally, you shouldn't be calling this as the code that creates
1467 /// the corpus for you should do it for you too.
1468 void
1470 {
1471  var_comp vc;
1472  std::sort(priv_->vars.begin(), priv_->vars.end(), vc);
1473 
1474  priv_->sorted_undefined_vars.clear();
1475  for (auto& f : priv_->undefined_vars)
1476  priv_->sorted_undefined_vars.push_back(f);
1477 
1478  std::sort(priv_->sorted_undefined_vars.begin(),
1479  priv_->sorted_undefined_vars.end(), vc);
1480 }
1481 
1482 /// Getter of the undefined functions of the corpus.
1483 ///
1484 /// Undefined functions are functions which symbols are not defined.
1485 ///
1486 /// @return a set of @ref function_decl* representing the functions
1487 /// that are undefined in the corpus.
1488 const corpus::functions_set&
1490 {return priv_->undefined_fns;}
1491 
1492 /// Getter of the undefined functions of the corpus.
1493 ///
1494 /// @return a set of @ref function_decl* representing the functions
1495 /// that are undefined in the corpus.
1498 {return priv_->undefined_fns;}
1499 
1500 /// Getter of the sorted vector of undefined functions of the corpus.
1501 ///
1502 /// @return a vector of @ref function_decl* representing the functions
1503 /// that are undefined in the corpus.
1504 const corpus::functions&
1506 {
1507  if (priv_->sorted_undefined_fns.empty()
1508  && !priv_->undefined_fns.empty())
1509  // We have undefined functions but we haven't sorted them yet.
1510  // Let's do the sorting now then.
1511  const_cast<corpus*>(this)->sort_functions();
1512 
1513  return priv_->sorted_undefined_fns;
1514 }
1515 
1516 /// Getter of the undefined variables of the corpus.
1517 ///
1518 /// @return a set of @ref var_decl* representing the variables that
1519 /// are undefined in the corpus.
1520 const corpus::variables_set&
1522 {return priv_->undefined_vars;}
1523 
1524 /// Getter of the undefined variables of the corpus.
1525 ///
1526 /// @return a set of @ref var_decl* representing the variables that
1527 /// are undefined in the corpus.
1530 {return priv_->undefined_vars;}
1531 
1532 /// Getter of the sorted vector of undefined variables of the corpus.
1533 ///
1534 /// @return a sorted vector of @ref var_decl* representing the
1535 /// variables that are undefined in the corpus.
1536 const corpus::variables&
1538 {
1539  if (priv_->sorted_undefined_vars.empty()
1540  && !priv_->undefined_vars.empty())
1541  // We have undefined variables but we haven't sorted them yet.
1542  // Let's do the sorting now then.
1543  const_cast<corpus*>(this)->sort_variables();
1544 
1545  return priv_->sorted_undefined_vars;
1546 }
1547 
1548 /// Getter of the set of function symbols that are not referenced by
1549 /// any function exported by the current corpus.
1550 ///
1551 /// When the corpus has been created from an ELF library or program,
1552 /// this function returns the set of function symbols not referenced
1553 /// by any debug information.
1554 ///
1555 /// @return the vector of function symbols not referenced by any
1556 /// function exported by the current corpus.
1557 const elf_symbols&
1559 {return priv_->get_unreferenced_function_symbols();}
1560 
1561 /// Getter of the set of variable symbols that are not referenced by
1562 /// any variable exported by the current corpus.
1563 ///
1564 /// When the corpus has been created from an ELF library or program,
1565 /// this function returns the set of variable symbols not referenced
1566 /// by any debug information.
1567 ///
1568 /// @return the vector of variable symbols not referenced by any
1569 /// variable exported by the current corpus.
1570 const elf_symbols&
1572 {return priv_->get_unreferenced_variable_symbols();}
1573 
1574 /// Accessor for the regex patterns describing the functions to drop
1575 /// from the public decl table.
1576 ///
1577 /// @return the regex patterns describing the functions to drop from
1578 /// the public decl table.
1579 vector<string>&
1581 {return priv_->regex_patterns_fns_to_suppress;}
1582 
1583 /// Accessor for the regex patterns describing the functions to drop
1584 /// from the public decl table.
1585 ///
1586 /// @return the regex patterns describing the functions to drop from
1587 /// the public decl table.
1588 const vector<string>&
1590 {return priv_->regex_patterns_fns_to_suppress;}
1591 
1592 /// Accessor for the regex patterns describing the variables to drop
1593 /// from the public decl table.
1594 ///
1595 /// @return the regex patterns describing the variables to drop from
1596 /// the public decl table.
1597 vector<string>&
1599 {return priv_->regex_patterns_vars_to_suppress;}
1600 
1601 /// Accessor for the regex patterns describing the variables to drop
1602 /// from the public decl table.
1603 ///
1604 /// @return the regex patterns describing the variables to drop from
1605 /// the public decl table.
1606 const vector<string>&
1608 {return priv_->regex_patterns_vars_to_suppress;}
1609 
1610 /// Accessor for the regex patterns describing the functions to keep
1611 /// into the public decl table. The other functions not matches by these
1612 /// regexes are dropped from the public decl table.
1613 ///
1614 /// @return the regex patterns describing the functions to keep into
1615 /// the public decl table.
1616 vector<string>&
1618 {return priv_->regex_patterns_fns_to_keep;}
1619 
1620 /// Accessor for the regex patterns describing the functions to keep
1621 /// into the public decl table. The other functions not matches by these
1622 /// regexes are dropped from the public decl table.
1623 ///
1624 /// @return the regex patterns describing the functions to keep into
1625 /// the public decl table.
1626 const vector<string>&
1628 {return priv_->regex_patterns_fns_to_keep;}
1629 
1630 /// Getter for the vector of function symbol IDs to keep.
1631 ///
1632 /// A symbol ID is a string made of the name of the symbol and its
1633 /// version, separated by one or two '@'.
1634 ///
1635 /// @return a vector of IDs of function symbols to keep.
1636 vector<string>&
1638 {return priv_->sym_id_fns_to_keep;}
1639 
1640 /// Getter for the vector of function symbol IDs to keep.
1641 ///
1642 /// A symbol ID is a string made of the name of the symbol and its
1643 /// version, separated by one or two '@'.
1644 ///
1645 /// @return a vector of IDs of function symbols to keep.
1646 const vector<string>&
1648 {return priv_->sym_id_fns_to_keep;}
1649 
1650 /// Accessor for the regex patterns describing the variables to keep
1651 /// into the public decl table. The other variables not matches by these
1652 /// regexes are dropped from the public decl table.
1653 ///
1654 /// @return the regex patterns describing the variables to keep into
1655 /// the public decl table.
1656 vector<string>&
1658 {return priv_->regex_patterns_vars_to_keep;}
1659 
1660 /// Accessor for the regex patterns describing the variables to keep
1661 /// into the public decl table. The other variables not matches by these
1662 /// regexes are dropped from the public decl table.
1663 ///
1664 /// @return the regex patterns describing the variables to keep into
1665 /// the public decl table.
1666 const vector<string>&
1668 {return priv_->regex_patterns_vars_to_keep;}
1669 
1670 /// Getter for the vector of variable symbol IDs to keep.
1671 ///
1672 /// A symbol ID is a string made of the name of the symbol and its
1673 /// version, separated by one or two '@'.
1674 ///
1675 /// @return a vector of IDs of variable symbols to keep.
1676 vector<string>&
1678 {return priv_->sym_id_vars_to_keep;}
1679 
1680 /// Getter for the vector of variable symbol IDs to keep.
1681 ///
1682 /// A symbol ID is a string made of the name of the symbol and its
1683 /// version, separated by one or two '@'.
1684 ///
1685 /// @return a vector of IDs of variable symbols to keep.
1686 const vector<string>&
1688 {return priv_->sym_id_vars_to_keep;}
1689 
1690 /// After the set of exported functions and variables have been built,
1691 /// consider all the tunables that control that set and see if some
1692 /// functions need to be removed from that set; if so, remove them.
1693 void
1695 {
1696  string sym_name, sym_version;
1697 
1698  functions fns_to_keep;
1700  for (auto f = priv_->fns.begin(); f != priv_->fns.end(); ++f)
1701  {
1702  if (b->priv_->keep_wrt_id_of_fns_to_keep(*f)
1703  && b->priv_->keep_wrt_regex_of_fns_to_suppress(*f)
1704  && b->priv_->keep_wrt_regex_of_fns_to_keep(*f))
1705  fns_to_keep.push_back(*f);
1706  }
1707  priv_->fns = fns_to_keep;
1708 
1709  variables vars_to_keep;
1710  for (auto v = priv_->vars.begin(); v != priv_->vars.end(); ++v)
1711  {
1712  if (b->priv_->keep_wrt_id_of_vars_to_keep(*v)
1713  && b->priv_->keep_wrt_regex_of_vars_to_suppress(*v)
1714  && b->priv_->keep_wrt_regex_of_vars_to_keep(*v))
1715  vars_to_keep.push_back(*v);
1716  }
1717  priv_->vars = vars_to_keep;
1718 }
1719 
1720 /// Getter for the object that is responsible for determining what
1721 /// decls ought to be in the set of exported decls.
1722 ///
1723 /// The object does have methods to add the decls to the set of
1724 /// exported decls, right at the place where the corpus expects it,
1725 /// so that there is no unnecessary copying involved.
1726 ///
1727 /// @return a (smart) pointer to the instance of @ref
1728 /// corpus::exported_decls_builder that is responsible for determine
1729 /// what decls ought to be in the set of exported decls.
1732 {
1733  if (!priv_->exported_decls_builder)
1734  {
1735  priv_->exported_decls_builder.reset
1736  (new exported_decls_builder(priv_->fns,
1737  priv_->vars,
1738  priv_->regex_patterns_fns_to_suppress,
1739  priv_->regex_patterns_vars_to_suppress,
1740  priv_->regex_patterns_fns_to_keep,
1741  priv_->regex_patterns_vars_to_keep,
1742  priv_->sym_id_fns_to_keep,
1743  priv_->sym_id_vars_to_keep));
1744  }
1745  return priv_->exported_decls_builder;
1746 }
1747 
1748 /// Bitwise | operator for the corpus::origin type.
1749 ///
1750 /// @param l the left-hand side operand of the | operation.
1751 ///
1752 /// @param r the right-hand side operand of the | operation.
1753 ///
1754 /// @return the result of the operation.
1757 {
1758  return static_cast<corpus::origin>
1759  (static_cast<uint32_t>(l) | static_cast<uint32_t>(r));
1760 }
1761 
1762 /// Bitwise |= operator for the corpus::origin type.
1763 ///
1764 /// @param l the left-hand side operand for the |= operation.
1765 ///
1766 /// @param r the right-hand side operand for the |= operation.
1767 ///
1768 /// @return the result of the operation.
1771 {
1772  l = l | r;
1773  return l;
1774 }
1775 
1776 /// Bitwise & operator for the corpus::origin type.
1777 ///
1778 /// @param l the left-hand side operand of the & operation.
1779 ///
1780 /// @param r the right-hand side operand of the & operation.
1781 ///
1782 /// @return the result of the operation.
1785 {
1786  return static_cast<corpus::origin>
1787  (static_cast<uint32_t>(l) & static_cast<uint32_t>(r));
1788 }
1789 
1790 /// Bitwise &= operator for the corpus::origin type.
1791 ///
1792 /// @param l the left-hand side operand of the &= operation.
1793 ///
1794 /// @param r the right-hand side operand of the &= operation.
1795 ///
1796 /// @return the result of the operation.
1799 {
1800  l = l & r;
1801  return l;
1802 }
1803 
1804 // </corpus stuff>
1805 
1806 // <corpus_group stuff>
1807 
1808 /// Type of the private data of @ref corpus_group
1809 struct corpus_group::priv
1810 {
1811  std::set<string> corpora_paths;
1812  corpora_type corpora;
1813  istring_function_decl_ptr_map_type fns_map;
1814  corpus::functions fns;
1815  istring_var_decl_ptr_map_type vars_map;
1816  corpus::variables vars;
1817  string_elf_symbols_map_type var_symbol_map;
1818  string_elf_symbols_map_type fun_symbol_map;
1819  elf_symbols sorted_var_symbols;
1820  elf_symbols sorted_fun_symbols;
1821  unordered_map<string, elf_symbol_sptr> unrefed_fun_symbol_map;
1822  elf_symbols unrefed_fun_symbols;
1823  bool unrefed_fun_symbols_built;
1824  unordered_map<string, elf_symbol_sptr> unrefed_var_symbol_map;
1825  elf_symbols unrefed_var_symbols;
1826  bool unrefed_var_symbols_built;
1827  unordered_set<interned_string, hash_interned_string> pub_type_pretty_reprs_;
1828 
1829  priv()
1830  : unrefed_fun_symbols_built(),
1831  unrefed_var_symbols_built()
1832  {}
1833 
1834  /// Add symbols to the set of corpus group function symbols that are
1835  /// *NOT* referenced by debug info.
1836  ///
1837  /// @param syms the set the symbols to add.
1838  void
1839  add_unref_fun_symbols(const elf_symbols& syms)
1840  {
1841  for (elf_symbols::const_iterator e =
1842  syms.begin(); e != syms.end(); ++e)
1843  {
1844  string sym_id = (*e)->get_id_string();
1845  unordered_map<string, elf_symbol_sptr>::const_iterator j =
1846  unrefed_fun_symbol_map.find(sym_id);
1847  if (j != unrefed_fun_symbol_map.end())
1848  continue;
1849 
1850  unrefed_fun_symbol_map[sym_id] = *e;
1851  unrefed_fun_symbols.push_back(*e);
1852  }
1853  unrefed_fun_symbols_built = true;
1854  }
1855 
1856  /// Add symbols to the set of corpus group variable symbols that are
1857  /// *NOT* referenced by debug info.
1858  ///
1859  /// @param syms the set the symbols to add.
1860  void
1861  add_unref_var_symbols(const elf_symbols& syms)
1862  {
1863  for (elf_symbols::const_iterator e =
1864  syms.begin(); e != syms.end(); ++e)
1865  {
1866  string sym_id = (*e)->get_id_string();
1867  unordered_map<string, elf_symbol_sptr>::const_iterator j =
1868  unrefed_var_symbol_map.find(sym_id);
1869  if (j != unrefed_var_symbol_map.end())
1870  continue;
1871 
1872  unrefed_var_symbol_map[sym_id] = *e;
1873  unrefed_var_symbols.push_back(*e);
1874  }
1875  unrefed_var_symbols_built = true;
1876  }
1877 }; // end corpus_group::priv
1878 
1879 /// Constructor of the @ref corpus_group type.
1880 ///
1881 /// @param env the environment of the @ref corpus_group.
1882 ///
1883 /// @param path the path to the file represented by the corpus group.
1884 corpus_group::corpus_group(const environment& env, const string& path = "")
1885  : corpus(env, path), priv_(new priv)
1886 {}
1887 
1888 /// Desctructor of the @ref corpus_group type.
1890 {}
1891 
1892 /// Add a new corpus to the current instance of @ref corpus_group.
1893 ///
1894 /// @param corp the new corpus to add.
1895 void
1896 corpus_group::add_corpus(const corpus_sptr& corp)
1897 {
1898  if (!corp)
1899  return;
1900 
1901  if (!corp->get_path().empty()
1902  && has_corpus(corp->get_path()))
1903  return;
1904 
1905  // Ensure the new architecture name matches the current one.
1906  string cur_arch = get_architecture_name(),
1907  corp_arch = corp->get_architecture_name();
1908  if (cur_arch.empty())
1909  set_architecture_name(corp_arch);
1910  else if (cur_arch != corp_arch)
1911  {
1912  std::cerr << "corpus '" << corp->get_path() << "'"
1913  << " has architecture '" << corp_arch << "'"
1914  << " but expected '" << cur_arch << "'\n";
1916  }
1917 
1918  priv_->corpora.push_back(corp);
1919  corp->set_group(this);
1920  priv_->corpora_paths.insert(corp->get_path());
1921 
1922  /// Add the unreferenced function and variable symbols of this
1923  /// corpus to the unreferenced symbols of the current corpus group.
1924  priv_->add_unref_fun_symbols(get_unreferenced_function_symbols());
1925  priv_->add_unref_var_symbols(get_unreferenced_variable_symbols());
1926 }
1927 
1928 /// Test if a corpus of a given path has been added to the group.
1929 ///
1930 /// @param path the path to the corpus to consider.
1931 ///
1932 /// @return true iff a corpus with path @p path is already present in
1933 /// the groupâ‹…
1934 bool
1935 corpus_group::has_corpus(const string& path)
1936 {
1937  if (priv_->corpora_paths.find(path) != priv_->corpora_paths.end())
1938  return true;
1939  return false;
1940 }
1941 
1942 /// Getter of the vector of corpora held by the current @ref
1943 /// corpus_group.
1944 ///
1945 /// @return the vector corpora.
1946 const corpus_group::corpora_type&
1948 {return priv_->corpora;}
1949 
1950 /// Getter of the first corpus added to this Group.
1951 ///
1952 /// @return the first corpus added to this Group.
1953 const corpus_sptr
1955 {return const_cast<corpus_group*>(this)->get_main_corpus();}
1956 
1957 /// Getter of the first corpus added to this Group.
1958 ///
1959 /// @return the first corpus added to this Group.
1960 corpus_sptr
1962 {
1963  if (!get_corpora().empty())
1964  return get_corpora().front();
1965  return corpus_sptr();
1966 }
1967 
1968 /// Test if the current corpus group is empty.
1969 ///
1970 /// @return true iff the current corpus group is empty.
1971 bool
1973 {return get_corpora().empty();}
1974 
1975 /// Get the functions exported by the corpora of the current corpus
1976 /// group.
1977 ///
1978 /// Upon its first invocation, this function walks the corpora
1979 /// contained in the corpus group and caches the functions they exported.
1980 ///
1981 /// Subsequent invocations just return the cached functions.
1982 ///
1983 /// @return the exported functions.
1984 const corpus::functions&
1986 {
1987  if (priv_->fns.empty())
1988  for (corpora_type::const_iterator i = get_corpora().begin();
1989  i != get_corpora().end();
1990  ++i)
1991  {
1992  corpus_sptr c = *i;
1993  for (corpus::functions::const_iterator f = c->get_functions().begin();
1994  f != c->get_functions().end();
1995  ++f)
1996  {
1997  interned_string fid = (*f)->get_id();
1998  istring_function_decl_ptr_map_type::const_iterator j =
1999  priv_->fns_map.find(fid);
2000 
2001  if (j != priv_->fns_map.end())
2002  // Don't cache the same function twice ...
2003  continue;
2004 
2005  priv_->fns_map[fid] = *f;
2006  // really cache the function now.
2007  priv_->fns.push_back(*f);
2008  }
2009  }
2010 
2011  return priv_->fns;
2012 }
2013 
2014 /// Get the global variables exported by the corpora of the current
2015 /// corpus group.
2016 ///
2017 /// Upon its first invocation, this function walks the corpora
2018 /// contained in the corpus group and caches the variables they
2019 /// export.
2020 ///
2021 /// @return the exported variables.
2022 const corpus::variables&
2024 {
2025  if (priv_->vars.empty())
2026  for (corpora_type::const_iterator i = get_corpora().begin();
2027  i != get_corpora().end();
2028  ++i)
2029  {
2030  corpus_sptr c = *i;
2031  for (corpus::variables::const_iterator v = c->get_variables().begin();
2032  v != c->get_variables().end();
2033  ++v)
2034  {
2035  interned_string vid = (*v)->get_id();
2036  istring_var_decl_ptr_map_type::const_iterator j =
2037  priv_->vars_map.find(vid);
2038 
2039  if (j != priv_->vars_map.end())
2040  // Don't cache the same variable twice ...
2041  continue;
2042 
2043  priv_->vars_map[vid] = *v;
2044  // Really cache the variable now.
2045  priv_->vars.push_back(*v);
2046  }
2047  }
2048 
2049  return priv_->vars;
2050 }
2051 
2052 /// Get the symbols of the global variables exported by the corpora of
2053 /// the current @ref corpus_group.
2054 ///
2055 /// @return the symbols of the global variables exported by the corpora
2058 {
2059  if (priv_->var_symbol_map.empty())
2060  for (corpora_type::const_iterator i = get_corpora().begin();
2061  i != get_corpora().end();
2062  ++i)
2063  priv_->var_symbol_map.insert((*i)->get_var_symbol_map().begin(),
2064  (*i)->get_var_symbol_map().end());
2065 
2066  return priv_->var_symbol_map;
2067 }
2068 
2069 /// Get the symbols of the global functions exported by the corpora of
2070 /// the current @ref corpus_group.
2071 ///
2072 /// @return the symbols of the global functions exported by the corpora
2075 {
2076  if (priv_->fun_symbol_map.empty())
2077  for (corpora_type::const_iterator i = get_corpora().begin();
2078  i != get_corpora().end();
2079  ++i)
2080  priv_->fun_symbol_map.insert((*i)->get_fun_symbol_map().begin(),
2081  (*i)->get_fun_symbol_map().end());
2082 
2083  return priv_->fun_symbol_map;
2084 }
2085 
2086 /// Get a sorted vector of the symbols of the functions exported by
2087 /// the corpora of the current group.
2088 ///
2089 /// @return the sorted vectors of the exported function symbols.
2090 const elf_symbols&
2092 {
2093  if (priv_->sorted_fun_symbols.empty()
2094  && !get_fun_symbol_map().empty())
2095  {
2096  for (corpora_type::const_iterator i = get_corpora().begin();
2097  i != get_corpora().end();
2098  ++i)
2099  {
2100  corpus_sptr c = *i;
2101  for (string_elf_symbols_map_type::const_iterator j =
2102  c->get_fun_symbol_map().begin();
2103  j != c->get_fun_symbol_map().begin();
2104  ++j)
2105  priv_->sorted_fun_symbols.insert(priv_->sorted_fun_symbols.end(),
2106  j->second.begin(),
2107  j->second.end());
2108  }
2109  comp_elf_symbols_functor comp;
2110  std::sort(priv_->sorted_fun_symbols.begin(),
2111  priv_->sorted_fun_symbols.end(),
2112  comp);
2113  }
2114 
2115  return priv_->sorted_fun_symbols;
2116 }
2117 
2118 /// Get a sorted vector of the symbols of the variables exported by
2119 /// the corpora of the current group.
2120 ///
2121 /// @return the sorted vectors of the exported variable symbols.
2122 const elf_symbols&
2124 {
2125  if (priv_->sorted_var_symbols.empty()
2126  && !get_var_symbol_map().empty())
2127  {
2128  for (corpora_type::const_iterator i = get_corpora().begin();
2129  i != get_corpora().end();
2130  ++i)
2131  {
2132  corpus_sptr c = *i;
2133  for (string_elf_symbols_map_type::const_iterator j =
2134  c->get_var_symbol_map().begin();
2135  j != c->get_var_symbol_map().begin();
2136  ++j)
2137  priv_->sorted_var_symbols.insert(priv_->sorted_var_symbols.end(),
2138  j->second.begin(),
2139  j->second.end());
2140  }
2141  comp_elf_symbols_functor comp;
2142  std::sort(priv_->sorted_var_symbols.begin(),
2143  priv_->sorted_var_symbols.end(),
2144  comp);
2145  }
2146 
2147  return priv_->sorted_var_symbols;
2148 }
2149 
2150 /// Get the set of function symbols not referenced by any debug info,
2151 /// from all the corpora of the current corpus group.
2152 ///
2153 /// Upon its first invocation, this function possibly walks all the
2154 /// copora of this corpus group and caches the unreferenced symbols
2155 /// they export. The function then returns the cache.
2156 ///
2157 /// Upon subsequent invocations, this functions just returns the
2158 /// cached symbols.
2159 ///
2160 /// @return the unreferenced symbols.
2161 const elf_symbols&
2163 {
2164  if (!priv_->unrefed_fun_symbols_built)
2165  if (priv_->unrefed_fun_symbols.empty())
2166  {
2167  for (corpora_type::const_iterator i = get_corpora().begin();
2168  i != get_corpora().end();
2169  ++i)
2170  {
2171  corpus_sptr c = *i;
2172  for (elf_symbols::const_iterator e =
2173  c->get_unreferenced_function_symbols().begin();
2174  e != c->get_unreferenced_function_symbols().end();
2175  ++e)
2176  {
2177  string sym_id = (*e)->get_id_string();
2178  unordered_map<string, elf_symbol_sptr>::const_iterator j =
2179  priv_->unrefed_fun_symbol_map.find(sym_id);
2180  if (j != priv_->unrefed_fun_symbol_map.end())
2181  continue;
2182 
2183  priv_->unrefed_fun_symbol_map[sym_id] = *e;
2184  priv_->unrefed_fun_symbols.push_back(*e);
2185  }
2186  }
2187  priv_->unrefed_fun_symbols_built = true;
2188  }
2189 
2190  return priv_->unrefed_fun_symbols;
2191 }
2192 
2193 /// Get the set of variable symbols not referenced by any debug info,
2194 /// from all the corpora of the current corpus group.
2195 ///
2196 /// Upon its first invocation, this function possibly walks all the
2197 /// copora of this corpus group and caches the unreferenced symbols
2198 /// they export. The function then returns the cache.
2199 ///
2200 /// Upon subsequent invocations, this functions just returns the
2201 /// cached symbols.
2202 ///
2203 /// @return the unreferenced symbols.
2204 const elf_symbols&
2206 {
2207  if (!priv_->unrefed_var_symbols_built)
2208  if (priv_->unrefed_var_symbols.empty())
2209  {
2210  for (corpora_type::const_iterator i = get_corpora().begin();
2211  i != get_corpora().end();
2212  ++i)
2213  {
2214  corpus_sptr c = *i;
2215  for (elf_symbols::const_iterator e =
2216  c->get_unreferenced_variable_symbols().begin();
2217  e != c->get_unreferenced_variable_symbols().end();
2218  ++e)
2219  {
2220  string sym_id = (*e)->get_id_string();
2221  unordered_map<string, elf_symbol_sptr>::const_iterator j =
2222  priv_->unrefed_var_symbol_map.find(sym_id);
2223  if (j != priv_->unrefed_var_symbol_map.end())
2224  continue;
2225 
2226  priv_->unrefed_var_symbol_map[sym_id] = *e;
2227  priv_->unrefed_var_symbols.push_back(*e);
2228  }
2229  }
2230  priv_->unrefed_var_symbols_built = true;
2231  }
2232 
2233  return priv_->unrefed_var_symbols;
2234 }
2235 
2236 /// Getter of a pointer to the set of types reachable from public
2237 /// interfaces of a given corpus group.
2238 unordered_set<interned_string, hash_interned_string>*
2240 {return &priv_->pub_type_pretty_reprs_;}
2241 
2242 /// Test if the recording of reachable types (and thus, indirectly,
2243 /// the recording of non-reachable types) is activated for the
2244 /// current @ref corpus_group.
2245 ///
2246 /// @return true iff the recording of reachable types is activated for
2247 /// the current @ref corpus_group.
2248 bool
2250 {return !get_public_types_pretty_representations()->empty();}
2251 
2252 // </corpus_group stuff>
2253 
2254 }// end namespace ir
2255 }// end namespace abigail
const variables & get_sorted_undefined_variables() const
Getter of the sorted vector of undefined variables of the corpus.
Definition: abg-corpus.cc:1537
const vector< type_base_wptr > & get_types_not_reachable_from_public_interfaces() const
Getter of a sorted vector of the types that are *NOT* reachable from public interfaces.
Definition: abg-corpus.cc:855
virtual bool recording_types_reachable_from_public_interface_supported()
Test if the recording of reachable types (and thus, indirectly, the recording of non-reachable types)...
Definition: abg-corpus.cc:806
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
Definition: abg-corpus.cc:1190
void sort_functions()
Sort the set of functions exported by this corpus.
Definition: abg-corpus.cc:1431
vector< string > & get_regex_patterns_of_fns_to_keep()
Accessor for the regex patterns describing the functions to keep into the public decl table...
Definition: abg-corpus.cc:1617
const variables_set & get_undefined_variables() const
Getter of the undefined variables of the corpus.
Definition: abg-corpus.cc:1521
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
Definition: abg-corpus.cc:1174
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:333
unordered_set< interned_string, hash_interned_string > * get_public_types_pretty_representations()
Getter of the set of pretty representation of types that are reachable from public interfaces (global...
Definition: abg-corpus.cc:636
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3117
void set_path(const string &)
Set the file path associated to the corpus file.
Definition: abg-corpus.cc:993
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
Definition: abg-corpus.cc:1163
string & get_format_minor_version_number() const
Getter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:960
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
bool maybe_add_var_to_exported_vars(const var_decl *)
Consider at all the tunables that control wether a variable should be added to the set of exported va...
Definition: abg-corpus.cc:192
Utilities to ease the wrapping of C types into std::shared_ptr.
void set_needed(const vector< string > &)
Setter of the needed property of the corpus.
Definition: abg-corpus.cc:1016
bool operator==(const corpus &) const
Compare the current corpus against another one.
Definition: abg-corpus.cc:1100
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition: abg-ir.cc:1214
const elf_symbols & get_unreferenced_function_symbols() const
Return a list of symbols that are not referenced by any function of corpus::get_functions().
Definition: abg-corpus.cc:441
An abstraction helper for type declarations.
Definition: abg-ir.h:1972
std::unordered_set< const var_decl * > variables_set
Convenience typedef for std::unordered_set.
Definition: abg-corpus.h:40
virtual const elf_symbols & get_unreferenced_variable_symbols() const
Get the set of variable symbols not referenced by any debug info, from all the corpora of the current...
Definition: abg-corpus.cc:2205
virtual const elf_symbols & get_sorted_fun_symbols() const
Get a sorted vector of the symbols of the functions exported by the corpora of the current group...
Definition: abg-corpus.cc:2091
void set_architecture_name(const string &)
Setter for the architecture name of the corpus.
Definition: abg-corpus.cc:1060
A comparison functor for pointers to var_decl.
Definition: abg-ir.h:4832
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:775
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:24
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:743
virtual const variables & get_variables() const
Return the public decl table of the global variables of the current corpus.
Definition: abg-corpus.cc:1461
void set_format_minor_version_number(const string &)
Setter of the minor version number of the abixml serialization format.
Definition: abg-corpus.cc:969
bool maybe_add_fn_to_exported_fns(function_decl *)
Consider at all the tunables that control wether a function should be added to the set of exported fu...
Definition: abg-corpus.cc:162
unordered_map< const var_decl *, bool, var_decl::hash, var_decl::ptr_equal > var_ptr_map_type
Convenience typedef for a hash map of pointer to var_decl and boolean.
Definition: abg-corpus.cc:230
virtual const functions & get_functions() const
Return the functions public decl table of the current corpus.
Definition: abg-corpus.cc:1379
const functions & exported_functions() const
Getter for the reference to the vector of exported functions. This vector is shared with with the cor...
Definition: abg-corpus.cc:101
std::set< translation_unit_sptr, shared_translation_unit_comp > translation_units
Convenience typedef for an ordered set of translation_unit_sptr.
Definition: abg-ir.h:851
vector< string > & get_regex_patterns_of_vars_to_keep()
Accessor for the regex patterns describing the variables to keep into the public decl table...
Definition: abg-corpus.cc:1657
virtual const corpus::functions & get_functions() const
Get the functions exported by the corpora of the current corpus group.
Definition: abg-corpus.cc:1985
bool empty() const
Test if the current instance of interned_string is empty.
const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
Definition: abg-corpus.cc:493
void sort_variables()
Sort the set of variables exported by this corpus.
Definition: abg-corpus.cc:1469
virtual const corpus::variables & get_variables() const
Get the global variables exported by the corpora of the current corpus group.
Definition: abg-corpus.cc:2023
const translation_unit_sptr find_translation_unit(const string &path) const
Find the translation unit that has a given path.
Definition: abg-corpus.cc:753
const string_elf_symbols_map_type & get_undefined_var_symbol_map() const
Return a map from name to undefined variable symbol for this corpus.
Definition: abg-corpus.cc:564
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:134
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:5051
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:2071
const var_decl * lookup_variable(const interned_string &id) const
Lookup the exported variable which has a given variable ID.
Definition: abg-corpus.cc:1417
vector< string > & get_sym_ids_of_vars_to_keep()
Getter for the vector of variable symbol IDs to keep.
Definition: abg-corpus.cc:1677
void set_soname(const string &)
Setter for the soname property of the corpus.
Definition: abg-corpus.cc:1038
string & get_format_major_version_number() const
Getter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:943
This contains the declarations for the symtab reader.
const corpora_type & get_corpora() const
Getter of the vector of corpora held by the current corpus_group.
Definition: abg-corpus.cc:1947
Abstracts a variable declaration.
Definition: abg-ir.h:3007
A functor to compare instances of var_decl base on their qualified names.
unordered_map< const function_decl *, bool, function_decl::hash, function_decl::ptr_equal > fn_ptr_map_type
Convenience typedef for a hash map of pointer to function_decl and boolean.
Definition: abg-corpus.cc:220
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
Definition: abg-ir.h:904
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
Definition: abg-corpus.cc:1004
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
Definition: abg-corpus.cc:1154
const elf_symbol_sptr lookup_variable_symbol(const string &n) const
Look in the variable symbols map for a symbol with a given name.
Definition: abg-corpus.cc:1312
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1798
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
Definition: abg-corpus.cc:884
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4422
virtual const elf_symbols & get_unreferenced_variable_symbols() const
Getter of the set of variable symbols that are not referenced by any variable exported by the current...
Definition: abg-corpus.cc:1571
void maybe_drop_some_exported_decls()
After the set of exported functions and variables have been built, consider all the tunables that con...
Definition: abg-corpus.cc:1694
Toplevel namespace for libabigail.
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Get the symbols of the global variables exported by the corpora of the current corpus_group.
Definition: abg-corpus.cc:2057
vector< const var_decl * > variables
Convenience typedef for std::vector
Definition: abg-corpus.h:37
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol...
Definition: abg-ir.h:909
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:50
This contains the private implementation of the suppression engine of libabigail. ...
~priv()
Destructor of the corpus::priv type.
Definition: abg-corpus.cc:676
unordered_set< interned_string, hash_interned_string > * get_public_types_pretty_representations()
Getter of a pointer to the set of types reachable from public interfaces of a given corpus group...
Definition: abg-corpus.cc:2239
Abstraction for a function declaration.
Definition: abg-ir.h:3110
virtual bool is_empty() const
Tests if the corpus is empty from an ABI surface perspective. I.e. if all of these criteria are true:...
Definition: abg-corpus.cc:1073
void add_corpus(const corpus_sptr &)
Add a new corpus to the current instance of corpus_group.
Definition: abg-corpus.cc:1896
Types of the main internal representation of libabigail.
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:5000
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition: abg-ir.cc:4817
vector< string > strings_type
A convenience typedef for std::vector.
Definition: abg-corpus.h:28
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4853
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
Definition: abg-corpus.cc:391
void add(const translation_unit_sptr &)
Add a translation unit to the current ABI Corpus.
Definition: abg-corpus.cc:723
unordered_map< string, const function_decl * > str_fn_ptr_map_type
Convenience typedef for a hash map of string and pointer to function_decl.
Definition: abg-corpus.cc:224
The type of the private data of corpus::exported_decls_builder type.
const functions_set & get_undefined_functions() const
Getter of the undefined functions of the corpus.
Definition: abg-corpus.cc:1489
This is a type that aggregates maps of all the kinds of types that are supported by libabigail...
Definition: abg-ir.h:592
const string_elf_symbols_map_type & get_undefined_var_symbol_map() const
Getter for the map of variable symbols that are undefined in this corpus.
Definition: abg-corpus.cc:1200
Abstraction of an elf symbol.
Definition: abg-ir.h:922
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:139
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Get the symbols of the global functions exported by the corpora of the current corpus_group.
Definition: abg-corpus.cc:2074
const elf_symbol_sptr lookup_function_symbol(const string &n) const
Look in the function symbols map for a symbol with a given name.
Definition: abg-corpus.cc:1209
virtual bool is_empty() const
Test if the current corpus group is empty.
Definition: abg-corpus.cc:1972
void drop_translation_units()
Erase the translation units contained in this in-memory object.
Definition: abg-corpus.cc:768
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:886
const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
Definition: abg-corpus.cc:349
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition: abg-fwd.h:88
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
Definition: abg-fwd.h:1714
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3883
const string_elf_symbols_map_type & get_fun_symbol_map() const
Return a map from name to function symbol for this corpus.
Definition: abg-corpus.cc:374
const string_elf_symbols_map_type & get_undefined_fun_symbol_map() const
Return a map from name to undefined function symbol for this corpus.
Definition: abg-corpus.cc:419
exported_decls_builder_sptr get_exported_decls_builder() const
Getter for the object that is responsible for determining what decls ought to be in the set of export...
Definition: abg-corpus.cc:1731
void record_type_as_reachable_from_public_interfaces(const type_base &)
Record a type as being reachable from public interfaces (global functions and variables).
Definition: abg-corpus.cc:817
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:333
const symtab_reader::symtab_sptr & get_symtab() const
Getter for the symtab object.
Definition: abg-corpus.cc:1126
std::unordered_set< function_decl * > * fn_id_maps_to_several_fns(const function_decl *)
Test if a given function ID maps to several functions in the same corpus.
Definition: abg-corpus.cc:125
string & get_path() const
Get the file path associated to the corpus file.
Definition: abg-corpus.cc:981
const corpus_sptr get_main_corpus() const
Getter of the first corpus added to this Group.
Definition: abg-corpus.cc:1954
const elf_symbols & get_unreferenced_variable_symbols() const
Return a list of symbols that are not referenced by any variable of corpus::get_variables().
Definition: abg-corpus.cc:586
const string_elf_symbols_map_type & get_var_symbol_map() const
Return a map from name to variable symbol for this corpus.
Definition: abg-corpus.cc:519
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1756
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return the pretty representation of this variable.
Definition: abg-ir.cc:21122
Equality functor for instances of function_decl.
Definition: abg-ir.h:4863
vector< string > & get_sym_ids_of_fns_to_keep()
Getter for the vector of function symbol IDs to keep.
Definition: abg-corpus.cc:1637
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4822
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2130
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:698
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1770
vector< string > & get_regex_patterns_of_fns_to_suppress()
Accessor for the regex patterns describing the functions to drop from the public decl table...
Definition: abg-corpus.cc:1580
void set_origin(origin)
Setter for the origin of the corpus.
Definition: abg-corpus.cc:935
virtual const elf_symbols & get_sorted_var_symbols() const
Get a sorted vector of the symbols of the variables exported by the corpora of the current group...
Definition: abg-corpus.cc:2123
The abstraction of an interned string.
vector< string > & get_regex_patterns_of_vars_to_suppress()
Accessor for the regex patterns describing the variables to drop from the public decl table...
Definition: abg-corpus.cc:1598
std::unordered_set< function_decl * > * lookup_functions(const interned_string &id)
Lookup the function which has a given function ID.
Definition: abg-corpus.cc:662
const functions & get_sorted_undefined_functions() const
Getter of the sorted vector of undefined functions of the corpus.
Definition: abg-corpus.cc:1505
void set_format_major_version_number(const string &)
Setter of the major version number of the abixml serialization format.
Definition: abg-corpus.cc:951
bool type_is_reachable_from_public_interfaces(const type_base &) const
Test if a type is reachable from public interfaces (global functions and variables).
Definition: abg-corpus.cc:835
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1193
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:892
The private data of the corpus type.
Abstraction of a group of corpora.
Definition: abg-corpus.h:382
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
Definition: abg-corpus.cc:1183
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:928
The private data and functions of the abigail::ir::corpus type.
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition: abg-ir.cc:9456
const variables & exported_variables() const
Getter for the reference to the vector of exported variables. This vector is shared with with the cor...
Definition: abg-corpus.cc:141
virtual const elf_symbols & get_unreferenced_function_symbols() const
Getter of the set of function symbols that are not referenced by any function exported by the current...
Definition: abg-corpus.cc:1558
const string & get_soname()
Getter for the soname property of the corpus.
Definition: abg-corpus.cc:1027
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1784
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
Definition: abg-corpus.cc:536
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
Definition: abg-corpus.cc:1119
virtual ~corpus_group()
Desctructor of the corpus_group type.
Definition: abg-corpus.cc:1889
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
Definition: abg-corpus.cc:1049
const std::unordered_set< function_decl * > * lookup_functions(const interned_string &id) const
Lookup the function which has a given function ID.
Definition: abg-corpus.cc:1397
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
Definition: abg-corpus.cc:1133
bool has_corpus(const string &)
Test if a corpus of a given path has been added to the group.
Definition: abg-corpus.cc:1935
virtual const elf_symbols & get_unreferenced_function_symbols() const
Get the set of function symbols not referenced by any debug info, from all the corpora of the current...
Definition: abg-corpus.cc:2162
bool do_log() const
Test if logging was requested.
Definition: abg-corpus.cc:705
std::unordered_set< const function_decl * > functions_set
Convenience typedef for std::unordered_set
Definition: abg-corpus.h:34
vector< const function_decl * > functions
Convenience typedef for std::vector
Definition: abg-corpus.h:31
const string_elf_symbols_map_type & get_undefined_fun_symbol_map() const
Getter for the map of function symbols that are undefined in this corpus.
Definition: abg-corpus.cc:1143
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr.
Definition: abg-corpus.h:42
virtual bool recording_types_reachable_from_public_interface_supported()
Test if the recording of reachable types (and thus, indirectly, the recording of non-reachable types)...
Definition: abg-corpus.cc:2249