From patchwork Fri Jul 3 16:46:39 2020 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: 39892 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 303E1384242F; Fri, 3 Jul 2020 16:47:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 303E1384242F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794878; bh=NGMR45e9WnXms2tqaAPKrDI+pIjrfU0/0GVHbDJO1Mw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=BReeCw1nOpmnVHvcQnQf4Uzi0Uhe6StIp7jt0k6CohX+esAqQW2Eg14hhN95uyVeG AIu+f78iedGfAvGovz867GnlQ1CAkdNRJvqvaG/Sm9NVMSu9mrIgBVynIMaiCxqckZ JOuHRWuLGKKQm5iIcpoPNOJ79/sl2AjqTc3kktnQ= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by sourceware.org (Postfix) with ESMTPS id 64A203844079 for ; Fri, 3 Jul 2020 16:47:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 64A203844079 Received: by mail-qv1-xf49.google.com with SMTP id g17so19171478qvw.0 for ; Fri, 03 Jul 2020 09:47:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NGMR45e9WnXms2tqaAPKrDI+pIjrfU0/0GVHbDJO1Mw=; b=gKn+5D6JOhJZze5zHnBjftyYNdCYa/DLacESmp5KG7JAXCEp4B9wP82olj+iA4A/iD kXmQK3ldtbGkznsk3YGXI81TeIrA09ih7I6zjB2ANzfmSgEIBP0Dbo+jr5xh5nnCUuC+ n8GkT7CDSBthyGmylP66OT8/bQkQL8AQkFenVQPf1xSXt83J8bd96xrkK2AezmWUdIyi PUS/wO7zjzxqvbcmKC5bOkSSxcvpj5iPL4ACVQ7ot0Eyu6k/FKRkLq0p9TMKRFTwKUZI h32jj6C9bdpClQKUdnBanSdRbnGksMe9f+ZFo3ac2KgybwdsVRuncdgtzF6fpLK8EGdb KaOg== X-Gm-Message-State: AOAM532gXrhJtkq0Z6GFRbodT5sbYXgPrGsweqMaj39ZKGJJ/sGJ6EFb ZXsSR72csoXw0os/5pBbuqQAjj8/IG0QqoLS3o6Y0AzeMyAryX5a8OLRRcRTnV3Fmh7KNK+TCOb EVbZLgbCQ7fNGP5V05+UCTOJP249tILxhzfoKatXjnsoBLzECdad7Qpgk8nYpxonhM1D72w8= X-Google-Smtp-Source: ABdhPJxl9FZGlRYA4x5K3ZCgIssrqm3MGsmLGdbpX73WM5s6mOvJqUNmTvA1ZpGHJGgS40DItWoyx4KeO4DONg== X-Received: by 2002:a0c:fcc9:: with SMTP id i9mr17303940qvq.152.1593794874877; Fri, 03 Jul 2020 09:47:54 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:39 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-10-maennich@google.com> Mime-Version: 1.0 References: <20200619214305.562-1-maennich@google.com> <20200703164651.1510825-1-maennich@google.com> X-Mailer: git-send-email 2.27.0.212.ge8ba1cc988-goog Subject: [PATCH v2 09/21] corpus: make get_unreferenced_(function|variable)_symbols use the new symtab To: libabigail@sourceware.org X-Spam-Status: No, score=-22.3 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. * src/abg-corpus-priv.h (corpus::priv::unrefed_var_symbols): make private, mutable and optional. (corpus::unrefed_fun_symbols): Likewise. (corpus::priv::get_unreferenced_function_symbols): New method declaration. (corpus::priv::get_unreferenced_variable_symbols): Likewise. * src/abg-corpus.cc (corpus::priv::build_unreferenced_symbols_tables): Delete method. (corpus::priv::get_unreferenced_function_symbols): New method implementation. (corpus::priv::get_unreferenced_variable_symbols): Likewise. (corpus::get_unreferenced_function_symbols): Proxy call to corpus::priv. (corpus::get_unreferenced_variable_symbols): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-corpus-priv.h | 13 ++- src/abg-corpus.cc | 261 ++++++++++++++++++++---------------------- 2 files changed, 131 insertions(+), 143 deletions(-) diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index ad96f260aa89..f2e895bf1e7d 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -702,8 +702,6 @@ struct corpus::priv symtab_reader::symtab_sptr symtab_; string_elf_symbols_map_sptr fun_symbol_map; string_elf_symbols_map_sptr undefined_fun_symbol_map; - elf_symbols unrefed_fun_symbols; - elf_symbols unrefed_var_symbols; // The type maps contained in this data member are populated if the // corpus follows the One Definition Rule and thus if there is only // one copy of a type with a given name, per corpus. Otherwise, if @@ -725,8 +723,10 @@ private: mutable abg_compat::optional sorted_var_symbols; mutable abg_compat::optional sorted_undefined_var_symbols; + mutable abg_compat::optional unrefed_var_symbols; mutable abg_compat::optional sorted_fun_symbols; mutable abg_compat::optional sorted_undefined_fun_symbols; + mutable abg_compat::optional unrefed_fun_symbols; public: priv(const string & p, @@ -738,9 +738,6 @@ public: pub_type_pretty_reprs_() {} - void - build_unreferenced_symbols_tables(); - type_maps& get_types(); @@ -753,12 +750,18 @@ public: const elf_symbols& get_sorted_undefined_fun_symbols() const; + const elf_symbols& + get_unreferenced_function_symbols() const; + const elf_symbols& get_sorted_var_symbols() const; const elf_symbols& get_sorted_undefined_var_symbols() const; + const elf_symbols& + get_unreferenced_variable_symbols() const; + unordered_set* get_public_types_pretty_representations(); diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 6d4bedfd57b7..0f5d51820891 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -317,132 +317,6 @@ struct comp_elf_symbols_functor // - -/// Build the tables of symbols that are not referenced by any -/// function or variables of corpus::get_functions() or -/// corpus::get_variables(). -/// -/// Note that this function considers the list of function and -/// variable symbols to keep, that is provided by -/// corpus::get_sym_ids_of_fns_to_keep() and -/// corpus::get_sym_ids_of_vars_to_keep(). If a given unreferenced -/// function or variable symbol is not in the list of variable and -/// function symbols to keep, then that symbol is dropped and will not -/// be part of the resulting table of unreferenced symbol that is -/// built. -/// -/// The built tables are accessible from -/// corpus::get_unreferenced_function_symbols() and -/// corpus::get_unreferenced_variable_symbols(). -void -corpus::priv::build_unreferenced_symbols_tables() -{ - unordered_map refed_funs, refed_vars; - elf_symbol_sptr sym; - - for (vector::const_iterator f = fns.begin(); - f != fns.end(); - ++f) - if ((sym = (*f)->get_symbol())) - { - refed_funs[sym->get_id_string()] = true; - for (elf_symbol_sptr a = sym->get_next_alias(); - a && !a->is_main_symbol(); - a = a->get_next_alias()) - refed_funs[a->get_id_string()] = true; - } - - for (vector::const_iterator v = vars.begin(); - v != vars.end(); - ++v) - if ((sym = (*v)->get_symbol())) - { - refed_vars[sym->get_id_string()] = true; - for (elf_symbol_sptr a = sym->get_next_alias(); - a && !a->is_main_symbol(); - a = a->get_next_alias()) - refed_vars[a->get_id_string()] = true; - } - - if (fun_symbol_map) - { - // Let's assume that the size of the unreferenced symbols vector - // is roughly smaller than the size of the symbol table. - unrefed_fun_symbols.reserve(fun_symbol_map->size()); - for (string_elf_symbols_map_type::const_iterator i - = fun_symbol_map->begin(); - i != fun_symbol_map->end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - { - string sym_id = (*s)->get_id_string(); - if (refed_funs.find(sym_id) == refed_funs.end()) - { - bool keep = sym_id_fns_to_keep.empty(); - for (vector::const_iterator i = - sym_id_fns_to_keep.begin(); - i != sym_id_fns_to_keep.end(); - ++i) - { - if (*i == sym_id) - { - keep = true; - break; - } - } - if (keep) - unrefed_fun_symbols.push_back(*s); - } - } - - comp_elf_symbols_functor comp; - std::sort(unrefed_fun_symbols.begin(), - unrefed_fun_symbols.end(), - comp); - } - - if (var_symbol_map) - { - // Let's assume that the size of the unreferenced symbols vector - // is roughly smaller than the size of the symbol table. - unrefed_var_symbols.reserve(var_symbol_map->size()); - for (string_elf_symbols_map_type::const_iterator i - = var_symbol_map->begin(); - i != var_symbol_map->end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - { - string sym_id = (*s)->get_id_string(); - if (refed_vars.find(sym_id) == refed_vars.end()) - { - bool keep = sym_id_vars_to_keep.empty(); - for (vector::const_iterator i = - sym_id_vars_to_keep.begin(); - i != sym_id_vars_to_keep.end(); - ++i) - { - if (*i == sym_id) - { - keep = true; - break; - } - } - if (keep) - unrefed_var_symbols.push_back(*s); - } - } - - comp_elf_symbols_functor comp; - std::sort(unrefed_var_symbols.begin(), - unrefed_var_symbols.end(), - comp); - } -} - /// Get the maps that associate a name to a certain kind of type. type_maps& corpus::priv::get_types() @@ -494,6 +368,66 @@ corpus::priv::get_sorted_undefined_fun_symbols() const return *sorted_undefined_fun_symbols; } +/// Return a list of symbols that are not referenced by any function of +/// corpus::get_functions(). +/// +/// Note that this function considers the list of function symbols to keep, +/// that is provided by corpus::get_sym_ids_of_fns_to_keep(). If a given +/// unreferenced function symbol is not in the list of functions to keep, then +/// that symbol is dropped and will not be part of the resulting table of +/// unreferenced symbol that is built. +const elf_symbols& +corpus::priv::get_unreferenced_function_symbols() const +{ + if (!unrefed_fun_symbols) + { + unrefed_fun_symbols = elf_symbols(); + if (symtab_) + { + unordered_map refed_funs; + elf_symbol_sptr sym; + + for (vector::const_iterator f = fns.begin(); + f != fns.end(); ++f) + if ((sym = (*f)->get_symbol())) + { + refed_funs[sym->get_id_string()] = true; + for (elf_symbol_sptr a = sym->get_next_alias(); + a && !a->is_main_symbol(); a = a->get_next_alias()) + refed_funs[a->get_id_string()] = true; + } + + symtab_reader::symtab_filter filter = + symtab_->make_filter().functions(); + for (symtab_reader::symtab::const_iterator iter = + symtab_->begin(filter); + iter != symtab_->end(); iter++) + { + const elf_symbol_sptr& symbol = *iter; + const std::string sym_id = symbol->get_id_string(); + + if (refed_funs.find(sym_id) == refed_funs.end()) + { + bool keep = sym_id_fns_to_keep.empty(); + for (vector::const_iterator i = + sym_id_fns_to_keep.begin(); + i != sym_id_fns_to_keep.end(); ++i) + { + if (*i == sym_id) + { + keep = true; + break; + } + } + if (keep) + unrefed_fun_symbols->push_back(symbol); + } + } + } + } + return *unrefed_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 @@ -535,6 +469,67 @@ corpus::priv::get_sorted_undefined_var_symbols() const return *sorted_undefined_var_symbols; } +/// Return a list of symbols that are not referenced by any variable of +/// corpus::get_variables(). +/// +/// Note that this function considers the list of variable symbols to keep, +/// that is provided by corpus::get_sym_ids_of_vars_to_keep(). If a given +/// unreferenced variable symbol is not in the list of variable to keep, then +/// that symbol is dropped and will not be part of the resulting table of +/// unreferenced symbol that is built. +const elf_symbols& +corpus::priv::get_unreferenced_variable_symbols() const +{ + if (!unrefed_var_symbols) + { + unrefed_var_symbols = elf_symbols(); + if (symtab_) + { + unordered_map refed_vars; + elf_symbol_sptr sym; + + for (vector::const_iterator f = vars.begin(); + f != vars.end(); ++f) + if ((sym = (*f)->get_symbol())) + { + refed_vars[sym->get_id_string()] = true; + for (elf_symbol_sptr a = sym->get_next_alias(); + a && !a->is_main_symbol(); a = a->get_next_alias()) + refed_vars[a->get_id_string()] = true; + } + + symtab_reader::symtab_filter filter = + symtab_->make_filter().variables(); + for (symtab_reader::symtab::const_iterator iter = + symtab_->begin(filter); + iter != symtab_->end(); iter++) + { + const elf_symbol_sptr& symbol = *iter; + const std::string sym_id = symbol->get_id_string(); + + if (refed_vars.find(sym_id) == refed_vars.end()) + { + bool keep = sym_id_vars_to_keep.empty(); + for (vector::const_iterator i = + sym_id_vars_to_keep.begin(); + i != sym_id_vars_to_keep.end(); ++i) + { + if (*i == sym_id) + { + keep = true; + break; + } + } + if (keep) + unrefed_var_symbols->push_back(symbol); + } + } + } + } + return *unrefed_var_symbols; +} + + /// Getter of the set of pretty representation of types that are /// reachable from public interfaces (global functions and variables). /// @@ -1366,12 +1361,7 @@ corpus::sort_variables() /// function exported by the current corpus. const elf_symbols& corpus::get_unreferenced_function_symbols() const -{ - if (priv_->unrefed_fun_symbols.empty() - && priv_->unrefed_var_symbols.empty()) - priv_->build_unreferenced_symbols_tables(); - return priv_->unrefed_fun_symbols; -} +{ return priv_->get_unreferenced_function_symbols(); } /// Getter of the set of variable symbols that are not referenced by /// any variable exported by the current corpus. @@ -1384,12 +1374,7 @@ corpus::get_unreferenced_function_symbols() const /// variable exported by the current corpus. const elf_symbols& corpus::get_unreferenced_variable_symbols() const -{ - if (priv_->unrefed_fun_symbols.empty() - && priv_->unrefed_var_symbols.empty()) - priv_->build_unreferenced_symbols_tables(); - return priv_->unrefed_var_symbols; -} +{ return priv_->get_unreferenced_variable_symbols(); } /// Accessor for the regex patterns describing the functions to drop /// from the public decl table.