/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
const char *name,
struct obstack *obstack)
{
- if (gsymbol->language == language_ada)
+ if (gsymbol->language () == language_ada)
{
if (name == NULL)
{
const char *
symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
{
- if (gsymbol->language == language_ada)
+ if (gsymbol->language () == language_ada)
{
if (!gsymbol->ada_mangled)
return NULL;
depending upon the language for the symbol. */
void
-symbol_set_language (struct general_symbol_info *gsymbol,
- enum language language,
- struct obstack *obstack)
+general_symbol_info::set_language (enum language language,
+ struct obstack *obstack)
{
- gsymbol->language = language;
- if (gsymbol->language == language_cplus
- || gsymbol->language == language_d
- || gsymbol->language == language_go
- || gsymbol->language == language_objc
- || gsymbol->language == language_fortran)
+ m_language = language;
+ if (language == language_cplus
+ || language == language_d
+ || language == language_go
+ || language == language_objc
+ || language == language_fortran)
{
- symbol_set_demangled_name (gsymbol, NULL, obstack);
+ symbol_set_demangled_name (this, NULL, obstack);
}
- else if (gsymbol->language == language_ada)
+ else if (language == language_ada)
{
- gdb_assert (gsymbol->ada_mangled == 0);
- gsymbol->language_specific.obstack = obstack;
+ gdb_assert (ada_mangled == 0);
+ language_specific.obstack = obstack;
}
else
{
- memset (&gsymbol->language_specific, 0,
- sizeof (gsymbol->language_specific));
+ memset (&language_specific, 0, sizeof (language_specific));
}
}
char *demangled = NULL;
int i;
- if (gsymbol->language == language_unknown)
- gsymbol->language = language_auto;
+ if (gsymbol->language () == language_unknown)
+ gsymbol->m_language = language_auto;
- if (gsymbol->language != language_auto)
+ if (gsymbol->language () != language_auto)
{
- const struct language_defn *lang = language_def (gsymbol->language);
+ const struct language_defn *lang = language_def (gsymbol->language ());
language_sniff_from_mangled_name (lang, mangled, &demangled);
return demangled;
if (language_sniff_from_mangled_name (lang, mangled, &demangled))
{
- gsymbol->language = l;
+ gsymbol->m_language = l;
return demangled;
}
}
so the pointer can be discarded after calling this function. */
void
-symbol_set_names (struct general_symbol_info *gsymbol,
- gdb::string_view linkage_name, bool copy_name,
- struct objfile_per_bfd_storage *per_bfd,
- gdb::optional<hashval_t> hash)
+general_symbol_info::compute_and_set_names (gdb::string_view linkage_name,
+ bool copy_name,
+ objfile_per_bfd_storage *per_bfd,
+ gdb::optional<hashval_t> hash)
{
struct demangled_name_entry **slot;
- if (gsymbol->language == language_ada)
+ if (language () == language_ada)
{
/* In Ada, we do the symbol lookups using the mangled name, so
we can save some space by not storing the demangled name. */
if (!copy_name)
- gsymbol->name = linkage_name.data ();
+ m_name = linkage_name.data ();
else
{
char *name = (char *) obstack_alloc (&per_bfd->storage_obstack,
memcpy (name, linkage_name.data (), linkage_name.length ());
name[linkage_name.length ()] = '\0';
- gsymbol->name = name;
+ m_name = name;
}
- symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
+ symbol_set_demangled_name (this, NULL, &per_bfd->storage_obstack);
return;
}
htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
&entry, *hash, INSERT));
+ /* The const_cast is safe because the only reason it is already
+ initialized is if we purposefully set it from a background
+ thread to avoid doing the work here. However, it is still
+ allocated from the heap and needs to be freed by us, just
+ like if we called symbol_find_demangled_name here. If this is
+ nullptr, we call symbol_find_demangled_name below, but we put
+ this smart pointer here to be sure that we don't leak this name. */
+ gdb::unique_xmalloc_ptr<char> demangled_name
+ (const_cast<char *> (language_specific.demangled_name));
+
/* If this name is not in the hash table, add it. */
if (*slot == NULL
/* A C version of the symbol may have already snuck into the table.
This happens to, e.g., main.init (__go_init_main). Cope. */
- || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
+ || (language () == language_go && (*slot)->demangled == nullptr))
{
/* A 0-terminated copy of the linkage name. Callers must set COPY_NAME
to true if the string might not be nullterminated. We have to make
else
linkage_name_copy = linkage_name;
- /* The const_cast is safe because the only reason it is already
- initialized is if we purposefully set it from a background
- thread to avoid doing the work here. However, it is still
- allocated from the heap and needs to be freed by us, just
- like if we called symbol_find_demangled_name here. */
- gdb::unique_xmalloc_ptr<char> demangled_name
- (gsymbol->language_specific.demangled_name
- ? const_cast<char *> (gsymbol->language_specific.demangled_name)
- : symbol_find_demangled_name (gsymbol, linkage_name_copy.data ()));
+ if (demangled_name.get () == nullptr)
+ demangled_name.reset
+ (symbol_find_demangled_name (this, linkage_name_copy.data ()));
/* Suppose we have demangled_name==NULL, copy_name==0, and
linkage_name_copy==linkage_name. In this case, we already have the
(gdb::string_view (mangled_ptr, linkage_name.length ()));
}
(*slot)->demangled = std::move (demangled_name);
- (*slot)->language = gsymbol->language;
+ (*slot)->language = language ();
}
- else if (gsymbol->language == language_unknown
- || gsymbol->language == language_auto)
- gsymbol->language = (*slot)->language;
+ else if (language () == language_unknown || language () == language_auto)
+ m_language = (*slot)->language;
- gsymbol->name = (*slot)->mangled.data ();
+ m_name = (*slot)->mangled.data ();
if ((*slot)->demangled != nullptr)
- symbol_set_demangled_name (gsymbol, (*slot)->demangled.get (),
+ symbol_set_demangled_name (this, (*slot)->demangled.get (),
&per_bfd->storage_obstack);
else
- symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
+ symbol_set_demangled_name (this, NULL, &per_bfd->storage_obstack);
}
/* See symtab.h. */
const char *
general_symbol_info::natural_name () const
{
- switch (language)
+ switch (language ())
{
case language_cplus:
case language_d:
default:
break;
}
- return name;
+ return linkage_name ();
}
/* See symtab.h. */
{
const char *dem_name = NULL;
- switch (language)
+ switch (language ())
{
case language_cplus:
case language_d:
const char *
general_symbol_info::search_name () const
{
- if (language == language_ada)
- return name;
+ if (language () == language_ada)
+ return linkage_name ();
else
return natural_name ();
}
const lookup_name_info &name)
{
symbol_name_matcher_ftype *name_match
- = get_symbol_name_matcher (language_def (gsymbol->language), name);
+ = get_symbol_name_matcher (language_def (gsymbol->language ()), name);
return name_match (gsymbol->search_name (), name, NULL);
}
if (!SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
return 0;
- if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- slot_domain, domain))
+ if (!symbol_matches_domain (sym->language (), slot_domain, domain))
return 0;
}
}
e.g. on PowerPC64, where the minimal symbol for a function will
point to the function descriptor, while the debug symbol will
point to the actual function code. */
- msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
+ msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->linkage_name (),
+ objfile);
if (msym)
ginfo->section = MSYMBOL_SECTION (msym);
else
So, instead, search the section table when lookup by name has
failed. The ``addr'' and ``endaddr'' fields may have already
- been relocated. If so, the relocation offset (i.e. the
- ANOFFSET value) needs to be subtracted from these values when
- performing the comparison. We unconditionally subtract it,
- because, when no relocation has been performed, the ANOFFSET
- value will simply be zero.
+ been relocated. If so, the relocation offset needs to be
+ subtracted from these values when performing the comparison.
+ We unconditionally subtract it, because, when no relocation
+ has been performed, the value will simply be zero.
The address of the symbol whose section we're fixing up HAS
NOT BEEN adjusted (relocated) yet. It can't have been since
ALL_OBJFILE_OSECTIONS (objfile, s)
{
int idx = s - objfile->sections;
- CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+ CORE_ADDR offset = objfile->section_offsets[idx];
if (fallback == -1)
fallback = idx;
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), domain))
+ if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
{
struct block_symbol block_sym = {sym, block};
/* See symtab.h. */
-void
+bool
global_symbol_searcher::add_matching_symbols
(objfile *objfile,
const gdb::optional<compiled_regex> &preg,
const gdb::optional<compiled_regex> &treg,
- std::vector<symbol_search> *results) const
+ std::set<symbol_search> *result_set) const
{
enum search_domain kind = m_kind;
&& SYMBOL_DOMAIN (sym) == MODULE_DOMAIN
&& SYMBOL_LINE (sym) != 0))))
{
- /* Matching msymbol, add it to the results list. */
- results->emplace_back (block, sym);
+ if (result_set->size () < m_max_search_results)
+ {
+ /* Match, insert if not already in the results. */
+ symbol_search ss (block, sym);
+ if (result_set->find (ss) == result_set->end ())
+ result_set->insert (ss);
+ }
+ else
+ return false;
}
}
}
}
+
+ return true;
}
/* See symtab.h. */
-void
+bool
global_symbol_searcher::add_matching_msymbols
(objfile *objfile, const gdb::optional<compiled_regex> &preg,
std::vector<symbol_search> *results) const
VAR_DOMAIN).symbol == NULL)
{
/* Matching msymbol, add it to the results list. */
- results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+ if (results->size () < m_max_search_results)
+ results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
+ else
+ return false;
}
}
}
}
}
-}
-/* Sort the symbols in RESULT and remove duplicates. */
-
-static void
-sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
-{
- std::sort (result->begin (), result->end ());
- result->erase (std::unique (result->begin (), result->end ()),
- result->end ());
+ return true;
}
/* See symtab.h. */
}
bool found_msymbol = false;
- std::vector<symbol_search> result;
+ std::set<symbol_search> result_set;
for (objfile *objfile : current_program_space->objfiles ())
{
/* Expand symtabs within objfile that possibly contain matching
symbols. */
found_msymbol |= expand_symtabs (objfile, preg);
- /* Find matching symbols within OBJFILE and add them in to the RESULT
- vector. */
- add_matching_symbols (objfile, preg, treg, &result);
+ /* Find matching symbols within OBJFILE and add them in to the
+ RESULT_SET set. Use a set here so that we can easily detect
+ duplicates as we go, and can therefore track how many unique
+ matches we have found so far. */
+ if (!add_matching_symbols (objfile, preg, treg, &result_set))
+ break;
}
- if (!result.empty ())
- sort_search_symbols_remove_dups (&result);
+ /* Convert the result set into a sorted result list, as std::set is
+ defined to be sorted then no explicit call to std::sort is needed. */
+ std::vector<symbol_search> result (result_set.begin (), result_set.end ());
/* If there are no debug symbols, then add matching minsyms. But if the
user wants to see symbols matching a type regexp, then never give a
{
gdb_assert (m_kind == VARIABLES_DOMAIN || m_kind == FUNCTIONS_DOMAIN);
for (objfile *objfile : current_program_space->objfiles ())
- add_matching_msymbols (objfile, preg, &result);
+ if (!add_matching_msymbols (objfile, preg, &result))
+ break;
}
return result;
const lookup_name_info &lookup_name,
const char *text, const char *word)
{
- completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym),
+ completion_list_add_name (tracker, sym->language (),
sym->natural_name (),
lookup_name, text, word);
}
const lookup_name_info &lookup_name,
const char *text, const char *word)
{
- completion_list_add_name (tracker, MSYMBOL_LANGUAGE (sym),
+ completion_list_add_name (tracker, sym->language (),
sym->natural_name (),
lookup_name, text, word);
}
if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
if (TYPE_FIELD_NAME (t, j))
- completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym),
+ completion_list_add_name (tracker, sym->language (),
TYPE_FIELD_NAME (t, j),
lookup_name, text, word);
}
return BMSYMBOL_VALUE_ADDRESS (found);
}
}
- return (minsym->value.address
- + ANOFFSET (objf->section_offsets, minsym->section));
+ return minsym->value.address + objf->section_offsets[minsym->section];
}
\f