]> sourceware.org Git - libabigail.git/commitdiff
corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab
authorMatthias Maennich <maennich@google.com>
Thu, 30 Apr 2020 14:35:08 +0000 (16:35 +0200)
committerDodji Seketeli <dodji@redhat.com>
Fri, 2 Apr 2021 08:40:10 +0000 (10:40 +0200)
Make the corresponding members an implementation detail of corpus::priv.
They get computed based on the new symtab whenever they are accessed
first with an atomic instantiation. That simplifies the implementation
and homogenizes the access to functions and variables. Sorting does not
need to be done as the symtab already gives a guarantee for that.

Due to improved alias detection in the new symtab reader, ensure we only
write symbol aliases to ksymtab symbols if having a ksymtab main symbol.

Test data needed to be adjusted as the new symtab reader is stricter in
regards to symbols listed in ksymtab. I.e. init_module is not an
exported symbol in the ksymtab of a kernel module.

* src/abg-corpus-priv.h (corpus::priv::sorted_var_symbols): make
  private, mutable and optional.
  (corpus::sorted_undefined_var_symbols): Likewise.
  (corpus::sorted_fun_symbols): Likewise.
  (corpus::sorted_undefined_fun_symbols): Likewise.
  (corpus::priv::get_sorted_fun_symbols): New method declaration.
  (corpus::priv::get_sorted_undefined_fun_symbols): Likewise.
  (corpus::priv::get_sorted_var_symbols): Likewise.
  (corpus::priv::get_sorted_undefined_var_symbols): Likewise.
* src/abg-corpus.cc
  (corpus::elf_symbol_comp_functor): Delete struct.
  (corpus::priv::get_sorted_fun_symbols): New method implementation.
  (corpus::priv::get_sorted_undefined_fun_symbols): Likewise.
  (corpus::priv::get_sorted_var_symbols): Likewise.
  (corpus::priv::get_sorted_undefined_var_symbols): Likewise.
  (corpus::get_sorted_fun_symbols): Proxy call to corpus::priv.
  (corpus::get_sorted_undefined_fun_symbols): Likewise.
  (corpus::get_sorted_var_symbols): Likewise.
  (corpus::get_sorted_undefined_var_symbols): Likewise.
* src/abg-writer.cc (write_elf_symbol_aliases): When emitting
  aliases for a kernel symbol, ensure to only emit exported,
  public aliases.
* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: update test
  data.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
src/abg-corpus-priv.h
src/abg-corpus.cc
src/abg-writer.cc
tests/data/test-read-dwarf/PR25007-sdhci.ko.abi

index 8ddec050bfbaf9179323bfe5aed19a3430e56573..3238ddf9501e803202f28b136d640b544dd97535 100644 (file)
@@ -686,13 +686,9 @@ struct corpus::priv
   vector<var_decl*>                            vars;
   string_elf_symbols_map_sptr                  var_symbol_map;
   string_elf_symbols_map_sptr                  undefined_var_symbol_map;
-  elf_symbols                                  sorted_var_symbols;
-  elf_symbols                                  sorted_undefined_var_symbols;
   symtab_reader::symtab_sptr                   symtab_;
   string_elf_symbols_map_sptr                  fun_symbol_map;
   string_elf_symbols_map_sptr                  undefined_fun_symbol_map;
-  elf_symbols                                  sorted_fun_symbols;
-  elf_symbols                                  sorted_undefined_fun_symbols;
   elf_symbols                                  unrefed_fun_symbols;
   elf_symbols                                  unrefed_var_symbols;
   // The type maps contained in this data member are populated if the
@@ -714,6 +710,11 @@ struct corpus::priv
 private:
   priv();
 
+  mutable abg_compat::optional<elf_symbols> sorted_var_symbols;
+  mutable abg_compat::optional<elf_symbols> sorted_undefined_var_symbols;
+  mutable abg_compat::optional<elf_symbols> sorted_fun_symbols;
+  mutable abg_compat::optional<elf_symbols> sorted_undefined_fun_symbols;
+
 public:
   priv(const string &  p,
        environment*    e)
@@ -733,6 +734,18 @@ public:
   const type_maps&
   get_types() const;
 
+  const elf_symbols&
+  get_sorted_fun_symbols() const;
+
+  const elf_symbols&
+  get_sorted_undefined_fun_symbols() const;
+
+  const elf_symbols&
+  get_sorted_var_symbols() const;
+
+  const elf_symbols&
+  get_sorted_undefined_var_symbols() const;
+
   unordered_set<interned_string, hash_interned_string>*
   get_public_types_pretty_representations();
 
index 426422c1db7e2d7b2d1b1662fa49e83281df88a1..9fd3b14324e7874c6deac745c15902ad4ea7fa3d 100644 (file)
@@ -427,6 +427,87 @@ const type_maps&
 corpus::priv::get_types() const
 {return types_;}
 
+/// Return a sorted vector of function symbols for this corpus.
+///
+/// Note that the first time this function is called, the symbols are
+/// sorted and cached.  Subsequent invocations of this function return
+/// the cached vector that was built previously.
+///
+/// @return the sorted list of function symbols.
+const elf_symbols&
+corpus::priv::get_sorted_fun_symbols() const
+{
+  if (!sorted_fun_symbols)
+    {
+      auto filter = symtab_->make_filter();
+      filter.set_functions();
+      sorted_fun_symbols = elf_symbols(symtab_->begin(filter), symtab_->end());
+    }
+  return *sorted_fun_symbols;
+}
+
+/// Getter for a sorted vector of the function symbols undefined in
+/// this corpus.
+///
+/// @return a vector of the function symbols undefined in this corpus,
+/// sorted by name and then version.
+const elf_symbols&
+corpus::priv::get_sorted_undefined_fun_symbols() const
+{
+  if (!sorted_undefined_fun_symbols)
+    {
+      auto filter = symtab_->make_filter();
+      filter.set_functions();
+      filter.set_undefined_symbols();
+      filter.set_public_symbols(false);
+
+      sorted_undefined_fun_symbols =
+       elf_symbols(symtab_->begin(filter), symtab_->end());
+    }
+  return *sorted_undefined_fun_symbols;
+}
+
+/// Getter for the sorted vector of variable symbols for this corpus.
+///
+/// Note that the first time this function is called, it computes the
+/// sorted vector, caches the result and returns it.  Subsequent
+/// invocations of this function just return the cached vector.
+///
+/// @return the sorted vector of variable symbols for this corpus.
+const elf_symbols&
+corpus::priv::get_sorted_var_symbols() const
+{
+  if (!sorted_var_symbols)
+    {
+      auto filter = symtab_->make_filter();
+      filter.set_variables();
+
+      sorted_var_symbols = elf_symbols(symtab_->begin(filter), symtab_->end());
+    }
+  return *sorted_var_symbols;
+}
+
+/// Getter for a sorted vector of the variable symbols undefined in
+/// this corpus.
+///
+/// @return a vector of the variable symbols undefined in this corpus,
+/// sorted by name and then version.
+const elf_symbols&
+corpus::priv::get_sorted_undefined_var_symbols() const
+{
+  if (!sorted_undefined_var_symbols)
+    {
+      auto filter = symtab_->make_filter();
+      filter.set_variables();
+      filter.set_undefined_symbols();
+      filter.set_public_symbols(false);
+
+      sorted_undefined_var_symbols =
+         elf_symbols(symtab_->begin(filter), symtab_->end());
+    }
+  return *sorted_undefined_var_symbols;
+}
+
 /// Getter of the set of pretty representation of types that are
 /// reachable from public interfaces (global functions and variables).
 ///
@@ -985,44 +1066,6 @@ const string_elf_symbols_map_type&
 corpus::get_undefined_fun_symbol_map() const
 {return *get_undefined_fun_symbol_map_sptr();}
 
-/// Functor to sort instances of @ref elf_symbol.
-struct elf_symbol_comp_functor
-{
-
-  /// Return true if the first argument is less than the second one.
-  ///
-  /// @param l the first parameter to consider.
-  ///
-  /// @param r the second parameter to consider.
-  ///
-  /// @return true if @p l is less than @p r
-  bool
-  operator()(elf_symbol& l, elf_symbol& r)
-  {return (l.get_id_string() < r.get_id_string());}
-
-  /// Return true if the first argument is less than the second one.
-  ///
-  /// @param l the first parameter to consider.
-  ///
-  /// @param r the second parameter to consider.
-  ///
-  /// @return true if @p l is less than @p r
-  bool
-  operator()(elf_symbol* l, elf_symbol* r)
-  {return operator()(*l, *r);}
-
-  /// Return true if the first argument is less than the second one.
-  ///
-  /// @param l the first parameter to consider.
-  ///
-  /// @param r the second parameter to consider.
-  ///
-  /// @return true if @p l is less than @p r
-  bool
-  operator()(elf_symbol_sptr l, elf_symbol_sptr r)
-  {return operator()(*l, *r);}
-}; // end struct elf_symbol_comp_functor
-
 /// Return a sorted vector of function symbols for this corpus.
 ///
 /// Note that the first time this function is called, the symbols are
@@ -1032,27 +1075,7 @@ struct elf_symbol_comp_functor
 /// @return the sorted list of function symbols.
 const elf_symbols&
 corpus::get_sorted_fun_symbols() const
-{
-  if (priv_->sorted_fun_symbols.empty()
-      && !get_fun_symbol_map().empty())
-    {
-      priv_->sorted_fun_symbols.reserve(get_fun_symbol_map().size());
-      for (string_elf_symbols_map_type::const_iterator i =
-            get_fun_symbol_map().begin();
-          i != get_fun_symbol_map().end();
-          ++i)
-       for (elf_symbols::const_iterator s = i->second.begin();
-            s != i->second.end();
-            ++s)
-         priv_->sorted_fun_symbols.push_back(*s);
-
-      elf_symbol_comp_functor comp;
-      std::sort(priv_->sorted_fun_symbols.begin(),
-               priv_->sorted_fun_symbols.end(),
-               comp);
-    }
-  return priv_->sorted_fun_symbols;
-}
+{return priv_->get_sorted_fun_symbols();}
 
 /// Getter for a sorted vector of the function symbols undefined in
 /// this corpus.
@@ -1061,28 +1084,27 @@ corpus::get_sorted_fun_symbols() const
 /// sorted by name and then version.
 const elf_symbols&
 corpus::get_sorted_undefined_fun_symbols() const
-{
-  if (priv_->sorted_undefined_fun_symbols.empty()
-      && !get_undefined_fun_symbol_map().empty())
-    {
-      priv_->sorted_undefined_fun_symbols.reserve
-       (get_undefined_fun_symbol_map().size());
-      for (string_elf_symbols_map_type::const_iterator i =
-            get_undefined_fun_symbol_map().begin();
-          i != get_undefined_fun_symbol_map().end();
-          ++i)
-       for (elf_symbols::const_iterator s = i->second.begin();
-            s != i->second.end();
-            ++s)
-         priv_->sorted_undefined_fun_symbols.push_back(*s);
+{return priv_->get_sorted_undefined_fun_symbols();}
 
-      elf_symbol_comp_functor comp;
-      std::sort(priv_->sorted_undefined_fun_symbols.begin(),
-               priv_->sorted_undefined_fun_symbols.end(),
-               comp);
-    }
-  return priv_->sorted_undefined_fun_symbols;
-}
+/// Getter for the sorted vector of variable symbols for this corpus.
+///
+/// Note that the first time this function is called, it computes the
+/// sorted vector, caches the result and returns it.  Subsequent
+/// invocations of this function just return the cached vector.
+///
+/// @return the sorted vector of variable symbols for this corpus.
+const elf_symbols&
+corpus::get_sorted_var_symbols() const
+{return priv_->get_sorted_var_symbols();}
+
+/// Getter for a sorted vector of the variable symbols undefined in
+/// this corpus.
+///
+/// @return a vector of the variable symbols undefined in this corpus,
+/// sorted by name and then version.
+const elf_symbols&
+corpus::get_sorted_undefined_var_symbols() const
+{return priv_->get_sorted_undefined_var_symbols();}
 
 /// Getter for the variable symbols map.
 ///
@@ -1122,65 +1144,6 @@ const string_elf_symbols_map_type&
 corpus::get_undefined_var_symbol_map() const
 {return *get_undefined_var_symbol_map_sptr();}
 
-/// Getter for the sorted vector of variable symbols for this corpus.
-///
-/// Note that the first time this function is called, it computes the
-/// sorted vector, caches the result and returns it.  Subsequent
-/// invocations of this function just return the cached vector.
-///
-/// @return the sorted vector of variable symbols for this corpus.
-const elf_symbols&
-corpus::get_sorted_var_symbols() const
-{
-  if (priv_->sorted_var_symbols.empty()
-      && !get_var_symbol_map().empty())
-    {
-      priv_->sorted_var_symbols.reserve(get_var_symbol_map().size());
-      for (string_elf_symbols_map_type::const_iterator i =
-            get_var_symbol_map().begin();
-          i != get_var_symbol_map().end();
-          ++i)
-       for (elf_symbols::const_iterator s = i->second.begin();
-            s != i->second.end(); ++s)
-         priv_->sorted_var_symbols.push_back(*s);
-
-      elf_symbol_comp_functor comp;
-      std::sort(priv_->sorted_var_symbols.begin(),
-               priv_->sorted_var_symbols.end(),
-               comp);
-    }
-  return priv_->sorted_var_symbols;
-}
-
-/// Getter for a sorted vector of the variable symbols undefined in
-/// this corpus.
-///
-/// @return a vector of the variable symbols undefined in this corpus,
-/// sorted by name and then version.
-const elf_symbols&
-corpus::get_sorted_undefined_var_symbols() const
-{
-  if (priv_->sorted_undefined_var_symbols.empty()
-      && !get_undefined_var_symbol_map().empty())
-    {
-      priv_->sorted_undefined_var_symbols.reserve
-       (get_undefined_var_symbol_map().size());
-      for (string_elf_symbols_map_type::const_iterator i =
-            get_undefined_var_symbol_map().begin();
-          i != get_undefined_var_symbol_map().end();
-          ++i)
-       for (elf_symbols::const_iterator s = i->second.begin();
-            s != i->second.end(); ++s)
-         priv_->sorted_undefined_var_symbols.push_back(*s);
-
-      elf_symbol_comp_functor comp;
-      std::sort(priv_->sorted_undefined_var_symbols.begin(),
-               priv_->sorted_undefined_var_symbols.end(),
-               comp);
-    }
-  return priv_->sorted_undefined_var_symbols;
-}
-
 /// Look in the function symbols map for a symbol with a given name.
 ///
 /// @param n the name of the symbol to look for.
index a961cc36b8f33ac226fc091048b4335ddb6c9a1d..a8778022a2c07419e045c610ab0439a8bb2a5b33 100644 (file)
@@ -1669,26 +1669,43 @@ write_elf_symbol_visibility(elf_symbol::visibility v, ostream& o)
 ///
 /// @return true upon successful completion.
 static bool
-write_elf_symbol_aliases(const elf_symbol& sym, ostream& o)
+write_elf_symbol_aliases(const elf_symbol& sym, ostream& out)
 {
   if (!sym.is_main_symbol() || !sym.has_aliases())
     return false;
 
-  bool emitted = false;
-  o << " alias='";
-  for (elf_symbol_sptr s = sym.get_next_alias();
-       !s->is_main_symbol();
+
+  std::vector<std::string> aliases;
+  for (elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
        s = s->get_next_alias())
     {
-      if (s->get_next_alias()->is_main_symbol())
-       o << s->get_id_string() << "'";
-      else
-       o << s->get_id_string() << ",";
+      if (!s->is_public())
+       continue;
+
+      if (s->is_suppressed())
+       continue;
+
+      if (sym.is_in_ksymtab() != s->is_in_ksymtab())
+       continue;
 
-      emitted = true;
+      aliases.push_back(s->get_id_string());
     }
 
-  return emitted;
+  if (!aliases.empty())
+    {
+      out << " alias='";
+      std::string separator;
+      for (const auto& alias : aliases)
+       {
+         out << separator << alias;
+         separator = ",";
+       }
+
+      out << "'";
+      return true;
+    }
+
+  return false;
 }
 
 /// Write an XML attribute for the reference to a symbol for the
index 38e7bbeade83ff76bdbf9d72817ec08e0ab0a7e9..84db4ad0b60f630903b2ceb71071acd0f622fd48 100644 (file)
@@ -2,8 +2,6 @@
   <elf-function-symbols>
     <elf-symbol name='__sdhci_add_host' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='__sdhci_read_caps' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
-    <elf-symbol name='cleanup_module' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
-    <elf-symbol name='init_module' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='sdhci_add_host' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='sdhci_adma_write_desc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
     <elf-symbol name='sdhci_alloc_host' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -40,7 +38,6 @@
     <elf-symbol name='sdhci_suspend_host' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
   </elf-function-symbols>
   <elf-variable-symbols>
-    <elf-symbol name='__this_module' size='896' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
   </elf-variable-symbols>
   <abi-instr address-size='64' path='/ws/android/kernel/aosp/common-mainline/common/drivers/mmc/host/sdhci.c' comp-dir-path='/ws/android/kernel/aosp/common-mainline/out/android-mainline/common' language='LANG_C89'>
     <type-decl name='__ARRAY_SIZE_TYPE__' size-in-bits='64' id='type-id-1'/>
This page took 0.199604 seconds and 5 git commands to generate.