From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from qproxy5-pub.mail.unifiedlayer.com (qproxy5-pub.mail.unifiedlayer.com [69.89.21.30]) by sourceware.org (Postfix) with ESMTPS id 1B99E3858C52 for ; Mon, 4 Apr 2022 19:54:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1B99E3858C52 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com Received: from gproxy4-pub.mail.unifiedlayer.com (gproxy4-pub.mail.unifiedlayer.com [69.89.23.142]) by qproxy5.mail.unifiedlayer.com (Postfix) with ESMTP id 7222280347E5 for ; Mon, 4 Apr 2022 19:54:15 +0000 (UTC) Received: from cmgw13.mail.unifiedlayer.com (unknown [10.0.90.128]) by progateway6.mail.pro1.eigbox.com (Postfix) with ESMTP id 38DD910048AB9 for ; Mon, 4 Apr 2022 19:53:45 +0000 (UTC) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTP id bSlknVklyY8ycbSlln7Zlk; Mon, 04 Apr 2022 19:53:45 +0000 X-Authority-Reason: nr=8 X-Authority-Analysis: v=2.4 cv=e+XD9Yl/ c=1 sm=1 tr=0 ts=624b4cc9 a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=dLZJa+xiwSxG16/P+YVxDGlgEgI=:19 a=z0gMJWrwH1QA:10:nop_rcvd_month_year a=Qbun_eYptAEA:10:endurance_base64_authed_username_1 a=XeNT5gEjx8JpRJrPfS8A:9 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=5xTmFav969EmEhxxYKZKiXnF5S+fyHgdGYJSWugKC88=; b=QqidyYWhKY7BuDiuqgu5J9HlOh 4JyyPQIRRacsjhgbNVyxvGE70mnk79r+VsHz0TQxlSJCLGiRK3er510ZHuFnasanX4kyn4J4y6RnP TlCVlLXtOJelHBXkpZ8JTUuWM; Received: from 71-211-176-135.hlrn.qwest.net ([71.211.176.135]:34802 helo=prentzel.Home) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nbSlk-003uHX-DG; Mon, 04 Apr 2022 13:53:44 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH v4 20/34] Implement quick_symbol_functions for cooked DWARF index Date: Mon, 4 Apr 2022 13:53:21 -0600 Message-Id: <20220404195335.2111906-21-tom@tromey.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220404195335.2111906-1-tom@tromey.com> References: <20220404195335.2111906-1-tom@tromey.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 71.211.176.135 X-Source-L: No X-Exim-ID: 1nbSlk-003uHX-DG X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 71-211-176-135.hlrn.qwest.net (prentzel.Home) [71.211.176.135]:34802 X-Source-Auth: tom+tromey.com X-Email-Count: 28 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-Spam-Status: No, score=-3030.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, JMQ_SPF_NEUTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Apr 2022 19:54:18 -0000 This implements quick_symbol_functions for the cooked DWARF index. This is the code that interfaces between the new index and the rest of gdb. Cooked indexes still aren't created by anything. For the most part this is straightforward. It shares some concepts with the existing DWARF indices. However, because names are stored pre-split in the cooked index, name lookup here is necessarily different; see expand_symtabs_matching for the gory details. --- gdb/dwarf2/read.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/dwarf2/read.h | 4 + 2 files changed, 281 insertions(+) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 38cbb91ac6a..74488930be6 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -91,6 +91,7 @@ #include #include "dwarf2/abbrev-cache.h" #include "cooked-index.h" +#include "split-name.h" /* When == 1, print basic high level tracing messages. When > 1, be more verbose. @@ -5567,6 +5568,8 @@ get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz) return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res); } +static quick_symbol_functions_up make_cooked_index_funcs (); + /* See dwarf2/public.h. */ void @@ -5644,6 +5647,13 @@ dwarf2_initialize_objfile (struct objfile *objfile) return; } + if (per_bfd->cooked_index_table != nullptr) + { + dwarf_read_debug_printf ("re-using cooked index table"); + objfile->qf.push_front (make_cooked_index_funcs ()); + return; + } + if (dwarf2_read_debug_names (per_objfile)) { dwarf_read_debug_printf ("found debug names"); @@ -19880,6 +19890,273 @@ cooked_indexer::make_index (cutu_reader *reader) } } +/* An implementation of quick_symbol_functions for the cooked DWARF + index. */ + +struct cooked_index_functions : public dwarf2_base_index_functions +{ + struct compunit_symtab *find_pc_sect_compunit_symtab + (struct objfile *objfile, struct bound_minimal_symbol msymbol, + CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override; + + struct compunit_symtab *find_compunit_symtab_by_address + (struct objfile *objfile, CORE_ADDR address) override; + + void dump (struct objfile *objfile) override + { + gdb_printf ("Cooked index in use\n"); + } + + void expand_matching_symbols + (struct objfile *, + const lookup_name_info &lookup_name, + domain_enum domain, + int global, + symbol_compare_ftype *ordered_compare) override; + + bool expand_symtabs_matching + (struct objfile *objfile, + gdb::function_view file_matcher, + const lookup_name_info *lookup_name, + gdb::function_view symbol_matcher, + gdb::function_view expansion_notify, + block_search_flags search_flags, + domain_enum domain, + enum search_domain kind) override; + + bool can_lazily_read_symbols () override + { + return true; + } + + void read_partial_symbols (struct objfile *objfile) override + { + if (dwarf2_has_info (objfile, nullptr)) + dwarf2_build_psymtabs (objfile); + } +}; + +struct compunit_symtab * +cooked_index_functions::find_pc_sect_compunit_symtab + (struct objfile *objfile, + struct bound_minimal_symbol msymbol, + CORE_ADDR pc, + struct obj_section *section, + int warn_if_readin) +{ + dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table == nullptr) + return nullptr; + + CORE_ADDR baseaddr = objfile->text_section_offset (); + dwarf2_per_cu_data *per_cu + = per_objfile->per_bfd->cooked_index_table->lookup (pc - baseaddr); + if (per_cu == nullptr) + return nullptr; + + if (warn_if_readin && per_objfile->symtab_set_p (per_cu)) + warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"), + paddress (objfile->arch (), pc)); + + compunit_symtab *result = (recursively_find_pc_sect_compunit_symtab + (dw2_instantiate_symtab (per_cu, per_objfile, + false), + pc)); + gdb_assert (result != nullptr); + return result; +} + +struct compunit_symtab * +cooked_index_functions::find_compunit_symtab_by_address + (struct objfile *objfile, CORE_ADDR address) +{ + if (objfile->sect_index_data == -1) + return nullptr; + + dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table == nullptr) + return nullptr; + + CORE_ADDR baseaddr = objfile->data_section_offset (); + dwarf2_per_cu_data *per_cu + = per_objfile->per_bfd->cooked_index_table->lookup (address - baseaddr); + if (per_cu == nullptr) + return nullptr; + + return dw2_instantiate_symtab (per_cu, per_objfile, false); +} + +void +cooked_index_functions::expand_matching_symbols + (struct objfile *objfile, + const lookup_name_info &lookup_name, + domain_enum domain, + int global, + symbol_compare_ftype *ordered_compare) +{ + dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table == nullptr) + return; + const block_search_flags search_flags = (global + ? SEARCH_GLOBAL_BLOCK + : SEARCH_STATIC_BLOCK); + const language_defn *lang = language_def (language_ada); + symbol_name_matcher_ftype *name_match + = lang->get_symbol_name_matcher (lookup_name); + + for (const cooked_index_entry *entry + : per_objfile->per_bfd->cooked_index_table->all_entries ()) + { + if (entry->parent_entry != nullptr) + continue; + + if (!entry->matches (search_flags) + || !entry->matches (domain)) + continue; + + if (name_match (entry->canonical, lookup_name, nullptr)) + dw2_instantiate_symtab (entry->per_cu, per_objfile, false); + } +} + +bool +cooked_index_functions::expand_symtabs_matching + (struct objfile *objfile, + gdb::function_view file_matcher, + const lookup_name_info *lookup_name, + gdb::function_view symbol_matcher, + gdb::function_view expansion_notify, + block_search_flags search_flags, + domain_enum domain, + enum search_domain kind) +{ + dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table == nullptr) + return true; + + dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher); + + /* This invariant is documented in quick-functions.h. */ + gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr); + if (lookup_name == nullptr) + { + for (dwarf2_per_cu_data *per_cu + : all_comp_units_range (per_objfile->per_bfd)) + { + QUIT; + + if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, + file_matcher, + expansion_notify)) + return false; + } + return true; + } + + lookup_name_info lookup_name_without_params + = lookup_name->make_ignore_params (); + bool completing = lookup_name->completion_mode (); + + /* Unique styles of language splitting. */ + static const enum language unique_styles[] = + { + /* No splitting is also a style. */ + language_c, + /* This includes Rust. */ + language_cplus, + /* This includes Go. */ + language_d, + language_ada + }; + + for (enum language lang : unique_styles) + { + std::vector name_vec + = lookup_name_without_params.split_name (lang); + + for (const cooked_index_entry *entry + : per_objfile->per_bfd->cooked_index_table->find (name_vec.back (), + completing)) + { + /* No need to consider symbols from expanded CUs. */ + if (per_objfile->symtab_set_p (entry->per_cu)) + continue; + + /* If file-matching was done, we don't need to consider + symbols from unmarked CUs. */ + if (file_matcher != nullptr && !entry->per_cu->v.quick->mark) + continue; + + /* See if the symbol matches the type filter. */ + if (!entry->matches (search_flags) + || !entry->matches (domain) + || !entry->matches (kind)) + continue; + + /* We've found the base name of the symbol; now walk its + parentage chain, ensuring that each component + matches. */ + bool found = true; + + const cooked_index_entry *parent = entry->parent_entry; + for (int i = name_vec.size () - 1; i > 0; --i) + { + /* If we ran out of entries, or if this segment doesn't + match, this did not match. */ + if (parent == nullptr + || strncmp (parent->name, name_vec[i - 1].data (), + name_vec[i - 1].length ()) != 0) + { + found = false; + break; + } + + parent = parent->parent_entry; + } + + if (!found) + continue; + + /* Might have been looking for "a::b" and found + "x::a::b". */ + if (symbol_matcher == nullptr) + { + symbol_name_match_type match_type + = lookup_name_without_params.match_type (); + if ((match_type == symbol_name_match_type::FULL + || (lang != language_ada + && match_type == symbol_name_match_type::EXPRESSION)) + && parent != nullptr) + continue; + } + else + { + auto_obstack temp_storage; + const char *full_name = entry->full_name (&temp_storage); + if (!symbol_matcher (full_name)) + continue; + } + + if (!dw2_expand_symtabs_matching_one (entry->per_cu, per_objfile, + file_matcher, + expansion_notify)) + return false; + } + } + + return true; +} + +/* Return a new cooked_index_functions object. */ + +static quick_symbol_functions_up +make_cooked_index_funcs () +{ + return quick_symbol_functions_up (new cooked_index_functions); +} + + + /* Returns nonzero if TAG represents a type that we might generate a partial symbol for. */ diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 06a35d59d28..4158a06e2bc 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -23,6 +23,7 @@ #include #include #include "dwarf2/comp-unit-head.h" +#include "dwarf2/cooked-index.h" #include "dwarf2/file-and-dir.h" #include "dwarf2/index-cache.h" #include "dwarf2/section.h" @@ -451,6 +452,9 @@ struct dwarf2_per_bfd /* The mapped index, or NULL if .debug_names is missing or not being used. */ std::unique_ptr debug_names_table; + /* The cooked index, or NULL if not using one. */ + std::unique_ptr cooked_index_table; + /* When using index_table, this keeps track of all quick_file_names entries. TUs typically share line table entries with a CU, so we maintain a separate table of all line table entries to support the sharing. -- 2.34.1