From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id 9A1AA3858D28; Tue, 12 Apr 2022 15:40:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9A1AA3858D28 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Implement quick_symbol_functions for cooked DWARF index X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: 2e57de7c843f03cfdce6a1a6b72c15afbaab9571 X-Git-Newrev: 698379cc2cab53d0c6de32ea8a955245b63e4a23 Message-Id: <20220412154046.9A1AA3858D28@sourceware.org> Date: Tue, 12 Apr 2022 15:40:46 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Apr 2022 15:40:46 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D698379cc2cab= 53d0c6de32ea8a955245b63e4a23 commit 698379cc2cab53d0c6de32ea8a955245b63e4a23 Author: Tom Tromey Date: Sat May 22 07:53:40 2021 -0600 Implement quick_symbol_functions for cooked DWARF index =20 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. =20 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. Diff: --- 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 2a3f3e71876..47f34738f10 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" =20 /* When =3D=3D 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); } =20 +static quick_symbol_functions_up make_cooked_index_funcs (); + /* See dwarf2/public.h. */ =20 void @@ -5644,6 +5647,13 @@ dwarf2_initialize_objfile (struct objfile *objfile) return; } =20 + if (per_bfd->cooked_index_table !=3D 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) } } =20 +/* 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) overri= de; + + 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_matche= r, + 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 =3D get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table =3D=3D nullptr) + return nullptr; + + CORE_ADDR baseaddr =3D objfile->text_section_offset (); + dwarf2_per_cu_data *per_cu + =3D per_objfile->per_bfd->cooked_index_table->lookup (pc - baseaddr); + if (per_cu =3D=3D 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 =3D (recursively_find_pc_sect_compunit_symtab + (dw2_instantiate_symtab (per_cu, per_objfile, + false), + pc)); + gdb_assert (result !=3D 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 =3D=3D -1) + return nullptr; + + dwarf2_per_objfile *per_objfile =3D get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table =3D=3D nullptr) + return nullptr; + + CORE_ADDR baseaddr =3D objfile->data_section_offset (); + dwarf2_per_cu_data *per_cu + =3D per_objfile->per_bfd->cooked_index_table->lookup (address - basead= dr); + if (per_cu =3D=3D 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 =3D get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table =3D=3D nullptr) + return; + const block_search_flags search_flags =3D (global + ? SEARCH_GLOBAL_BLOCK + : SEARCH_STATIC_BLOCK); + const language_defn *lang =3D language_def (language_ada); + symbol_name_matcher_ftype *name_match + =3D 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 !=3D 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_match= er, + gdb::function_view expansion_notify, + block_search_flags search_flags, + domain_enum domain, + enum search_domain kind) +{ + dwarf2_per_objfile *per_objfile =3D get_dwarf2_per_objfile (objfile); + if (per_objfile->per_bfd->cooked_index_table =3D=3D 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 !=3D nullptr || symbol_matcher =3D=3D nullptr); + if (lookup_name =3D=3D 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 + =3D lookup_name->make_ignore_params (); + bool completing =3D lookup_name->completion_mode (); + + /* Unique styles of language splitting. */ + static const enum language unique_styles[] =3D + { + /* 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 + =3D 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 !=3D 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 =3D true; + + const cooked_index_entry *parent =3D entry->parent_entry; + for (int i =3D 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 =3D=3D nullptr + || strncmp (parent->name, name_vec[i - 1].data (), + name_vec[i - 1].length ()) !=3D 0) + { + found =3D false; + break; + } + + parent =3D parent->parent_entry; + } + + if (!found) + continue; + + /* Might have been looking for "a::b" and found + "x::a::b". */ + if (symbol_matcher =3D=3D nullptr) + { + symbol_name_match_type match_type + =3D lookup_name_without_params.match_type (); + if ((match_type =3D=3D symbol_name_match_type::FULL + || (lang !=3D language_ada + && match_type =3D=3D symbol_name_match_type::EXPRESSION)) + && parent !=3D nullptr) + continue; + } + else + { + auto_obstack temp_storage; + const char *full_name =3D 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); +} + +=0C + /* Returns nonzero if TAG represents a type that we might generate a parti= al symbol for. */ =20 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 @@ public: /* The mapped index, or NULL if .debug_names is missing or not being use= d. */ std::unique_ptr debug_names_table; =20 + /* 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 entr= ies. TUs typically share line table entries with a CU, so we maintain a separate table of all line table entries to support the sharing.