/* Partial symbol tables.
- Copyright (C) 2009-2017 Free Software Foundation, Inc.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "cp-support.h"
#include "gdbcmd.h"
#include <algorithm>
+#include <set>
struct psymbol_bcache
{
{
const language_defn *lang = language_def (SYMBOL_LANGUAGE (psym));
symbol_name_matcher_ftype *name_match
- = language_get_symbol_name_matcher (lang, lookup_name);
+ = get_symbol_name_matcher (lang, lookup_name);
return name_match (SYMBOL_SEARCH_NAME (psym), lookup_name, NULL);
}
const struct section_offsets *new_offsets,
const struct section_offsets *delta)
{
- struct partial_symbol **psym;
struct partial_symtab *p;
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
if (SYMBOL_SECTION (psym) >= 0)
SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym));
}
+
+ objfile->psymbol_map.clear ();
}
/* Psymtab version of find_last_source_symtab. See its definition in
to handle cases like the file being moved. */
if (ps->fullname == NULL)
{
- int fd = find_and_open_source (ps->filename, ps->dirname, &ps->fullname);
+ gdb::unique_xmalloc_ptr<char> fullname;
+ int fd = find_and_open_source (ps->filename, ps->dirname, &fullname);
+ ps->fullname = fullname.release ();
if (fd >= 0)
close (fd);
else
{
- gdb::unique_xmalloc_ptr<char> fullname;
-
/* rewrite_source_path would be applied by find_and_open_source, we
should report the pathname where GDB tried to find the file. */
}
partial_symbol **gbound
- = &objfile->global_psymbols[ps->globals_offset + ps->n_global_syms];
+ = objfile->global_psymbols.data () + ps->globals_offset + ps->n_global_syms;
partial_symbol **sbound
- = &objfile->static_psymbols[ps->statics_offset + ps->n_static_syms];
+ = objfile->static_psymbols.data () + ps->statics_offset + ps->n_static_syms;
partial_symbol **bound = gbound;
/* Go through all of the symbols stored in a partial
symtab in one loop. */
- partial_symbol **psym = &objfile->global_psymbols[ps->globals_offset];
+ partial_symbol **psym = objfile->global_psymbols.data () + ps->globals_offset;
while (keep_going)
{
if (psym >= bound)
{
if (bound == gbound && ps->n_static_syms != 0)
{
- psym = &objfile->static_psymbols[ps->statics_offset];
+ psym = objfile->static_psymbols.data () + ps->statics_offset;
bound = sbound;
}
else
return objfile->psymtabs != NULL;
}
+/* Helper function for psym_find_compunit_symtab_by_address that fills
+ in psymbol_map for a given range of psymbols. */
+
+static void
+psym_fill_psymbol_map (struct objfile *objfile,
+ struct partial_symtab *psymtab,
+ std::set<CORE_ADDR> *seen_addrs,
+ const std::vector<partial_symbol *> &symbols,
+ int start,
+ int length)
+{
+ for (int i = 0; i < length; ++i)
+ {
+ struct partial_symbol *psym = symbols[start + i];
+
+ if (PSYMBOL_CLASS (psym) == LOC_STATIC)
+ {
+ CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (psym);
+ if (seen_addrs->find (addr) == seen_addrs->end ())
+ {
+ seen_addrs->insert (addr);
+ objfile->psymbol_map.emplace_back (addr, psymtab);
+ }
+ }
+ }
+}
+
+/* See find_compunit_symtab_by_address in quick_symbol_functions, in
+ symfile.h. */
+
+static compunit_symtab *
+psym_find_compunit_symtab_by_address (struct objfile *objfile,
+ CORE_ADDR address)
+{
+ if (objfile->psymbol_map.empty ())
+ {
+ struct partial_symtab *pst;
+
+ std::set<CORE_ADDR> seen_addrs;
+
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
+ {
+ psym_fill_psymbol_map (objfile, pst,
+ &seen_addrs,
+ objfile->global_psymbols,
+ pst->globals_offset,
+ pst->n_global_syms);
+ psym_fill_psymbol_map (objfile, pst,
+ &seen_addrs,
+ objfile->static_psymbols,
+ pst->statics_offset,
+ pst->n_static_syms);
+ }
+
+ objfile->psymbol_map.shrink_to_fit ();
+
+ std::sort (objfile->psymbol_map.begin (), objfile->psymbol_map.end (),
+ [] (const std::pair<CORE_ADDR, partial_symtab *> &a,
+ const std::pair<CORE_ADDR, partial_symtab *> &b)
+ {
+ return a.first < b.first;
+ });
+ }
+
+ auto iter = std::lower_bound
+ (objfile->psymbol_map.begin (), objfile->psymbol_map.end (), address,
+ [] (const std::pair<CORE_ADDR, partial_symtab *> &a,
+ CORE_ADDR b)
+ {
+ return a.first < b;
+ });
+
+ if (iter == objfile->psymbol_map.end () || iter->first != address)
+ return NULL;
+
+ return psymtab_to_symtab (objfile, iter->second);
+}
+
const struct quick_symbol_functions psym_functions =
{
psym_has_symbols,
psym_map_matching_symbols,
psym_expand_symtabs_matching,
psym_find_pc_sect_compunit_symtab,
+ psym_find_compunit_symtab_by_address,
psym_map_symbol_filenames
};
h = hash_continue (&lang, sizeof (unsigned int), h);
h = hash_continue (&domain, sizeof (unsigned int), h);
h = hash_continue (&theclass, sizeof (unsigned int), h);
- h = hash_continue (psymbol->ginfo.name, strlen (psymbol->ginfo.name), h);
+ /* Note that psymbol names are interned via symbol_set_names, so
+ there's no need to hash the contents of the name here. */
+ h = hash_continue (&psymbol->ginfo.name, sizeof (psymbol->ginfo.name), h);
return h;
}
&& sym1->ginfo.language == sym2->ginfo.language
&& PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
&& PSYMBOL_CLASS (sym1) == PSYMBOL_CLASS (sym2)
+ /* Note that psymbol names are interned via
+ symbol_set_names, so there's no need to compare the
+ contents of the name here. */
&& sym1->ginfo.name == sym2->ginfo.name);
}
length = ps->n_static_syms;
while (length--)
{
- sym = block_lookup_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
+ sym = block_lookup_symbol (b, SYMBOL_SEARCH_NAME (*psym),
+ symbol_name_match_type::SEARCH_NAME,
SYMBOL_DOMAIN (*psym));
if (!sym)
{
length = ps->n_global_syms;
while (length--)
{
- sym = block_lookup_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
+ sym = block_lookup_symbol (b, SYMBOL_SEARCH_NAME (*psym),
+ symbol_name_match_type::SEARCH_NAME,
SYMBOL_DOMAIN (*psym));
if (!sym)
{