Support wildmatching in .debug_names too.
dw2_debug_names_expand_symtabs_matching currently doesn't support symbol_name_match_type::WILD, it always matches symbol names fully. The .gdb_index code supports via dw2_expand_symtabs_matching_symbol, which builds the mapped_index::name_components table on demand, and then binary searches that table. The .debug_names names index is pretty much the same as the .gdb_index names index, i.e., a list of fully-qualified names with no parameter/overload info. (There's no what-is-the-language-of-symbol-name info in .debug_names either, unfortunately.) So this fixes .debug_names by factoring out the related .gdb_index code out of the mapped_index class to a base class that is inherited by both the .gdb_index (mapped_index) and .debug_names (mapped_debug_names) map classes. gdb/ChangeLog: 2017-12-08 Pedro Alves <palves@redhat.com> * dwarf2read.c (struct mapped_index_base): New, partially factored out from ... (struct mapped_index): ... this. Inherit mapped_index_base. (mapped_index::symbol_name_slot_invalid): (mapped_index::symbol_name_at): Add override marker. (mapped_index::symbol_name_count): New. (struct mapped_debug_names): Inherit mapped_index_base. (mapped_debug_names::symbol_name_at): New. (mapped_debug_names::symbol_name_count): New. (mapped_index::find_name_components_bounds): Rename to ... (mapped_index_base::find_name_components_bounds): ... this. (mapped_index::build_name_components): Rename to ... (mapped_index_base::build_name_components): ... this. Adjust to use mapped_index_base::symbol_name_count and mapped_index_base::symbol_name_slot_invalid. (dw2_expand_symtabs_matching_symbol): Take a mapped_index_base instead of a mapped_index. Use dw2_expand_symtabs_matching_symbol.
This commit is contained in:
parent
f00a2de2a7
commit
44ed8f3ed0
|
@ -1,3 +1,24 @@
|
||||||
|
2017-12-08 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* dwarf2read.c (struct mapped_index_base): New, partially factored
|
||||||
|
out from ...
|
||||||
|
(struct mapped_index): ... this. Inherit mapped_index_base.
|
||||||
|
(mapped_index::symbol_name_slot_invalid):
|
||||||
|
(mapped_index::symbol_name_at): Add override marker.
|
||||||
|
(mapped_index::symbol_name_count): New.
|
||||||
|
(struct mapped_debug_names): Inherit mapped_index_base.
|
||||||
|
(mapped_debug_names::symbol_name_at): New.
|
||||||
|
(mapped_debug_names::symbol_name_count): New.
|
||||||
|
(mapped_index::find_name_components_bounds): Rename to ...
|
||||||
|
(mapped_index_base::find_name_components_bounds): ... this.
|
||||||
|
(mapped_index::build_name_components): Rename to ...
|
||||||
|
(mapped_index_base::build_name_components): ... this. Adjust to
|
||||||
|
use mapped_index_base::symbol_name_count and
|
||||||
|
mapped_index_base::symbol_name_slot_invalid.
|
||||||
|
(dw2_expand_symtabs_matching_symbol): Take a mapped_index_base
|
||||||
|
instead of a mapped_index. Use
|
||||||
|
dw2_expand_symtabs_matching_symbol.
|
||||||
|
|
||||||
2017-12-08 Pedro Alves <palves@redhat.com>
|
2017-12-08 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* dwarf2read.c (mapped_index::symbol_table_slot): New.
|
* dwarf2read.c (mapped_index::symbol_table_slot): New.
|
||||||
|
|
116
gdb/dwarf2read.c
116
gdb/dwarf2read.c
|
@ -234,9 +234,50 @@ struct name_component
|
||||||
offset_type idx;
|
offset_type idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Base class containing bits shared by both .gdb_index and
|
||||||
|
.debug_name indexes. */
|
||||||
|
|
||||||
|
struct mapped_index_base
|
||||||
|
{
|
||||||
|
/* The name_component table (a sorted vector). See name_component's
|
||||||
|
description above. */
|
||||||
|
std::vector<name_component> name_components;
|
||||||
|
|
||||||
|
/* How NAME_COMPONENTS is sorted. */
|
||||||
|
enum case_sensitivity name_components_casing;
|
||||||
|
|
||||||
|
/* Return the number of names in the symbol table. */
|
||||||
|
virtual size_t symbol_name_count () const = 0;
|
||||||
|
|
||||||
|
/* Get the name of the symbol at IDX in the symbol table. */
|
||||||
|
virtual const char *symbol_name_at (offset_type idx) const = 0;
|
||||||
|
|
||||||
|
/* Return whether the name at IDX in the symbol table should be
|
||||||
|
ignored. */
|
||||||
|
virtual bool symbol_name_slot_invalid (offset_type idx) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the symbol name component sorted vector, if we haven't
|
||||||
|
yet. */
|
||||||
|
void build_name_components ();
|
||||||
|
|
||||||
|
/* Returns the lower (inclusive) and upper (exclusive) bounds of the
|
||||||
|
possible matches for LN_NO_PARAMS in the name component
|
||||||
|
vector. */
|
||||||
|
std::pair<std::vector<name_component>::const_iterator,
|
||||||
|
std::vector<name_component>::const_iterator>
|
||||||
|
find_name_components_bounds (const lookup_name_info &ln_no_params) const;
|
||||||
|
|
||||||
|
/* Prevent deleting/destroying via a base class pointer. */
|
||||||
|
protected:
|
||||||
|
~mapped_index_base() = default;
|
||||||
|
};
|
||||||
|
|
||||||
/* A description of the mapped index. The file format is described in
|
/* A description of the mapped index. The file format is described in
|
||||||
a comment by the code that writes the index. */
|
a comment by the code that writes the index. */
|
||||||
struct mapped_index
|
struct mapped_index : public mapped_index_base
|
||||||
{
|
{
|
||||||
/* A slot/bucket in the symbol table hash. */
|
/* A slot/bucket in the symbol table hash. */
|
||||||
struct symbol_table_slot
|
struct symbol_table_slot
|
||||||
|
@ -260,33 +301,24 @@ struct mapped_index
|
||||||
/* A pointer to the constant pool. */
|
/* A pointer to the constant pool. */
|
||||||
const char *constant_pool;
|
const char *constant_pool;
|
||||||
|
|
||||||
/* The name_component table (a sorted vector). See name_component's
|
bool symbol_name_slot_invalid (offset_type idx) const override
|
||||||
description above. */
|
{
|
||||||
std::vector<name_component> name_components;
|
const auto &bucket = this->symbol_table[idx];
|
||||||
|
return bucket.name == 0 && bucket.vec;
|
||||||
/* How NAME_COMPONENTS is sorted. */
|
}
|
||||||
enum case_sensitivity name_components_casing;
|
|
||||||
|
|
||||||
/* Convenience method to get at the name of the symbol at IDX in the
|
/* Convenience method to get at the name of the symbol at IDX in the
|
||||||
symbol table. */
|
symbol table. */
|
||||||
const char *symbol_name_at (offset_type idx) const
|
const char *symbol_name_at (offset_type idx) const override
|
||||||
{ return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
|
{ return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
|
||||||
|
|
||||||
/* Build the symbol name component sorted vector, if we haven't
|
size_t symbol_name_count () const override
|
||||||
yet. */
|
{ return this->symbol_table.size (); }
|
||||||
void build_name_components ();
|
|
||||||
|
|
||||||
/* Returns the lower (inclusive) and upper (exclusive) bounds of the
|
|
||||||
possible matches for LN_NO_PARAMS in the name component
|
|
||||||
vector. */
|
|
||||||
std::pair<std::vector<name_component>::const_iterator,
|
|
||||||
std::vector<name_component>::const_iterator>
|
|
||||||
find_name_components_bounds (const lookup_name_info &ln_no_params) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A description of the mapped .debug_names.
|
/* A description of the mapped .debug_names.
|
||||||
Uninitialized map has CU_COUNT 0. */
|
Uninitialized map has CU_COUNT 0. */
|
||||||
struct mapped_debug_names
|
struct mapped_debug_names : public mapped_index_base
|
||||||
{
|
{
|
||||||
bfd_endian dwarf5_byte_order;
|
bfd_endian dwarf5_byte_order;
|
||||||
bool dwarf5_is_dwarf64;
|
bool dwarf5_is_dwarf64;
|
||||||
|
@ -320,6 +352,15 @@ struct mapped_debug_names
|
||||||
std::unordered_map<ULONGEST, index_val> abbrev_map;
|
std::unordered_map<ULONGEST, index_val> abbrev_map;
|
||||||
|
|
||||||
const char *namei_to_name (uint32_t namei) const;
|
const char *namei_to_name (uint32_t namei) const;
|
||||||
|
|
||||||
|
/* Implementation of the mapped_index_base virtual interface, for
|
||||||
|
the name_components cache. */
|
||||||
|
|
||||||
|
const char *symbol_name_at (offset_type idx) const override
|
||||||
|
{ return namei_to_name (idx); }
|
||||||
|
|
||||||
|
size_t symbol_name_count () const override
|
||||||
|
{ return this->name_count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
|
typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
|
||||||
|
@ -4595,7 +4636,7 @@ make_sort_after_prefix_name (const char *search_name)
|
||||||
|
|
||||||
std::pair<std::vector<name_component>::const_iterator,
|
std::pair<std::vector<name_component>::const_iterator,
|
||||||
std::vector<name_component>::const_iterator>
|
std::vector<name_component>::const_iterator>
|
||||||
mapped_index::find_name_components_bounds
|
mapped_index_base::find_name_components_bounds
|
||||||
(const lookup_name_info &lookup_name_without_params) const
|
(const lookup_name_info &lookup_name_without_params) const
|
||||||
{
|
{
|
||||||
auto *name_cmp
|
auto *name_cmp
|
||||||
|
@ -4668,7 +4709,7 @@ mapped_index::find_name_components_bounds
|
||||||
/* See declaration. */
|
/* See declaration. */
|
||||||
|
|
||||||
void
|
void
|
||||||
mapped_index::build_name_components ()
|
mapped_index_base::build_name_components ()
|
||||||
{
|
{
|
||||||
if (!this->name_components.empty ())
|
if (!this->name_components.empty ())
|
||||||
return;
|
return;
|
||||||
|
@ -4684,11 +4725,10 @@ mapped_index::build_name_components ()
|
||||||
D use '.'), then we'll need to try splitting the symbol name
|
D use '.'), then we'll need to try splitting the symbol name
|
||||||
according to that language too. Note that Ada does support wild
|
according to that language too. Note that Ada does support wild
|
||||||
matching, but doesn't currently support .gdb_index. */
|
matching, but doesn't currently support .gdb_index. */
|
||||||
for (offset_type idx = 0; idx < this->symbol_table.size (); ++idx)
|
auto count = this->symbol_name_count ();
|
||||||
|
for (offset_type idx = 0; idx < count; idx++)
|
||||||
{
|
{
|
||||||
auto &bucket = this->symbol_table[idx];
|
if (this->symbol_name_slot_invalid (idx))
|
||||||
|
|
||||||
if (bucket.name == 0 && bucket.vec == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char *name = this->symbol_name_at (idx);
|
const char *name = this->symbol_name_at (idx);
|
||||||
|
@ -4727,15 +4767,15 @@ mapped_index::build_name_components ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for dw2_expand_symtabs_matching that works with a
|
/* Helper for dw2_expand_symtabs_matching that works with a
|
||||||
mapped_index instead of the containing objfile. This is split to a
|
mapped_index_base instead of the containing objfile. This is split
|
||||||
separate function in order to be able to unit test the
|
to a separate function in order to be able to unit test the
|
||||||
name_components matching using a mock mapped_index. For each
|
name_components matching using a mock mapped_index_base. For each
|
||||||
symbol name that matches, calls MATCH_CALLBACK, passing it the
|
symbol name that matches, calls MATCH_CALLBACK, passing it the
|
||||||
symbol's index in the mapped_index symbol table. */
|
symbol's index in the mapped_index_base symbol table. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dw2_expand_symtabs_matching_symbol
|
dw2_expand_symtabs_matching_symbol
|
||||||
(mapped_index &index,
|
(mapped_index_base &index,
|
||||||
const lookup_name_info &lookup_name_in,
|
const lookup_name_info &lookup_name_in,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
enum search_domain kind,
|
enum search_domain kind,
|
||||||
|
@ -5435,8 +5475,6 @@ dw2_expand_symtabs_matching
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind)
|
enum search_domain kind)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
dw2_setup (objfile);
|
dw2_setup (objfile);
|
||||||
|
|
||||||
/* index_table is NULL if OBJF_READNOW. */
|
/* index_table is NULL if OBJF_READNOW. */
|
||||||
|
@ -6393,16 +6431,12 @@ dw2_debug_names_expand_symtabs_matching
|
||||||
|
|
||||||
dw_expand_symtabs_matching_file_matcher (file_matcher);
|
dw_expand_symtabs_matching_file_matcher (file_matcher);
|
||||||
|
|
||||||
const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
|
mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
|
||||||
|
|
||||||
for (uint32_t namei = 0; namei < map.name_count; ++namei)
|
dw2_expand_symtabs_matching_symbol (map, lookup_name,
|
||||||
|
symbol_matcher,
|
||||||
|
kind, [&] (offset_type namei)
|
||||||
{
|
{
|
||||||
QUIT;
|
|
||||||
|
|
||||||
const char *const namei_string = map.namei_to_name (namei);
|
|
||||||
if (symbol_matcher != NULL && !symbol_matcher (namei_string))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* The name was matched, now expand corresponding CUs that were
|
/* The name was matched, now expand corresponding CUs that were
|
||||||
marked. */
|
marked. */
|
||||||
dw2_debug_names_iterator iter (map, kind, namei);
|
dw2_debug_names_iterator iter (map, kind, namei);
|
||||||
|
@ -6411,7 +6445,7 @@ dw2_debug_names_expand_symtabs_matching
|
||||||
while ((per_cu = iter.next ()) != NULL)
|
while ((per_cu = iter.next ()) != NULL)
|
||||||
dw2_expand_symtabs_matching_one (per_cu, file_matcher,
|
dw2_expand_symtabs_matching_one (per_cu, file_matcher,
|
||||||
expansion_notify);
|
expansion_notify);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct quick_symbol_functions dwarf2_debug_names_functions =
|
const struct quick_symbol_functions dwarf2_debug_names_functions =
|
||||||
|
|
Loading…
Reference in New Issue