From patchwork Wed Jan 27 12:58:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Matthias_M=C3=A4nnich?= X-Patchwork-Id: 41841 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DD1A73973009; Wed, 27 Jan 2021 12:59:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DD1A73973009 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1611752365; bh=2oMhQD0te+7uH1CsgcygqjHyzCdfmH05pkiKfvpM408=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ZOtH1viueCXW/dS3vSN8lZOqbKGmRDsbMV9p2kK03mE/YVjS7xM+gybNKB+kyIhDw 1NXFWY3aYRvtdgova266vQbX/qb9WWKUs5BWJ0K64VkyX2ErmFdEpuJfYslCo+F6UK 4ndeshY7ToRgAPIwMurxdjKGFpZGr3HfOuSs02VU= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by sourceware.org (Postfix) with ESMTPS id 7A67F3973009 for ; Wed, 27 Jan 2021 12:59:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 7A67F3973009 Received: by mail-qt1-x849.google.com with SMTP id d26so1026675qtr.0 for ; Wed, 27 Jan 2021 04:59:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=2oMhQD0te+7uH1CsgcygqjHyzCdfmH05pkiKfvpM408=; b=APQUJ4fyUBe99putKKT1q1bu5BfAIRfHMHRuJXKen/csUVnbFFXxVBTMVLOUM9+d39 i+GU3oJugQMosbQXZZeP4NchQxwBG9a5zuNyufEjGTa0kLwxW8OG1UDEaNYs0w1gp2Cy PN49TzYoSf7FMsvhaXX71iNcLl5ILe1COsphSOTUUY6oHC6+hE4p5cf766xT/zL2jQ7r zzydgkEdLb+uAMLp5ISYGL57iijkMV1H109v61Mf/R8aMrID6keFmWszAjtqUnS1Gbp3 mWzEl6hsvCl4dK6UxEWll4lxUF3UGGozn57CeImT6UXTVUUQyOqMmqcNSbt2Fw1n3X5B gZMA== X-Gm-Message-State: AOAM5314uy+v3D3/TCbD8Kiqw321dWe9yMx2E7SAGASE1tx/TdJ1HGkK hzp/Z7dsKp/Xy1HvoX3KiExaw5GqyY8q64A3eF0c0V6Lh68jzzHsKxPQdBvzMYnPiBrIvgvKU5e 2qc13mPmOOx4uYYzdVcO0gKR/C05bYNffJCCmBwmpaE6xkEpQIYVdnllK0J60FqlLXE19tb8= X-Google-Smtp-Source: ABdhPJwOH07mJoJteeUQ0suIQkCRCiOyji8G3JViv+gFO6tvHxNdBn921v5S+O9/sSPCJoic80vLhn6xe/cBnQ== X-Received: from lux.lon.corp.google.com ([2a00:79e0:d:210:7220:84ff:fe09:a3aa]) (user=maennich job=sendgmr) by 2002:ad4:4f83:: with SMTP id em3mr8736152qvb.28.1611752361986; Wed, 27 Jan 2021 04:59:21 -0800 (PST) Date: Wed, 27 Jan 2021 12:58:40 +0000 In-Reply-To: <20210127125853.886677-1-maennich@google.com> Message-Id: <20210127125853.886677-8-maennich@google.com> Mime-Version: 1.0 References: <20200619214305.562-1-maennich@google.com> <20210127125853.886677-1-maennich@google.com> X-Mailer: git-send-email 2.30.0.280.ga3ce27912f-goog Subject: [PATCH 07/20] corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab To: libabigail@sourceware.org X-Spam-Status: No, score=-22.1 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Matthias Maennich via Libabigail From: =?utf-8?q?Matthias_M=C3=A4nnich?= Reply-To: Matthias Maennich Cc: maennich@google.com, kernel-team@android.com Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" 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 Signed-off-by: Matthias Maennich --- src/abg-corpus-priv.h | 21 +- src/abg-corpus.cc | 241 +++++++----------- src/abg-writer.cc | 39 ++- .../data/test-read-dwarf/PR25007-sdhci.ko.abi | 3 - 4 files changed, 135 insertions(+), 169 deletions(-) diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index 290e19c60e67..282796e1b685 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -683,13 +683,9 @@ struct corpus::priv vector 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 @@ -711,6 +707,11 @@ struct corpus::priv private: priv(); + mutable abg_compat::optional sorted_var_symbols; + mutable abg_compat::optional sorted_undefined_var_symbols; + mutable abg_compat::optional sorted_fun_symbols; + mutable abg_compat::optional sorted_undefined_fun_symbols; + public: priv(const string & p, environment* e) @@ -730,6 +731,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* get_public_types_pretty_representations(); diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 0d5849ddac5d..75f897eb72a8 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -438,6 +438,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). /// @@ -933,104 +1014,21 @@ 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 -/// 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::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); +{ return priv_->get_sorted_fun_symbols(); } - elf_symbol_comp_functor comp; - std::sort(priv_->sorted_fun_symbols.begin(), - priv_->sorted_fun_symbols.end(), - comp); - } - return priv_->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::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; -} +const elf_symbols& +corpus::get_sorted_var_symbols() const +{ return priv_->get_sorted_var_symbols(); } + +const elf_symbols& +corpus::get_sorted_undefined_var_symbols() const +{ return priv_->get_sorted_undefined_var_symbols(); } /// Getter for the variable symbols map. /// @@ -1070,65 +1068,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. diff --git a/src/abg-writer.cc b/src/abg-writer.cc index d55bbbc166d5..d4d5e5531894 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -1678,26 +1678,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 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 diff --git a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi index 44e2e608260b..1167e5aa478a 100644 --- a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi +++ b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi @@ -2,8 +2,6 @@ - - @@ -40,7 +38,6 @@ -