/* Partial symbol tables.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "command.h"
#include "readline/readline.h"
#include "gdb_regex.h"
+#include "dictionary.h"
+#include "language.h"
+#include "cp-support.h"
#ifndef DEV_TTY
#define DEV_TTY "/dev/tty"
#define PSYMTAB_TO_SYMTAB(pst) \
((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
-/* Lookup a partial symbol. */
+static struct partial_symbol *match_partial_symbol (struct partial_symtab *,
+ int,
+ const char *, domain_enum,
+ symbol_compare_ftype *,
+ symbol_compare_ftype *);
+
static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
const char *, int,
domain_enum);
static struct symtab *psymtab_to_symtab (struct partial_symtab *pst);
-/* Lookup the partial symbol table of a source file named NAME.
- *If* there is no '/' in the name, a match after a '/'
- in the psymtab filename will also work. */
+/* Ensure that the partial symbols for OBJFILE have been loaded. This
+ function always returns its argument, as a convenience. */
-static struct partial_symtab *
-lookup_partial_symtab (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path)
+struct objfile *
+require_partial_symbols (struct objfile *objfile, int verbose)
+{
+ if ((objfile->flags & OBJF_PSYMTABS_READ) == 0)
+ {
+ objfile->flags |= OBJF_PSYMTABS_READ;
+
+ if (objfile->sf->sym_read_psymbols)
+ {
+ if (verbose)
+ {
+ printf_unfiltered (_("Reading symbols from %s..."),
+ objfile->name);
+ gdb_flush (gdb_stdout);
+ }
+ (*objfile->sf->sym_read_psymbols) (objfile);
+ if (verbose)
+ {
+ if (!objfile_has_symbols (objfile))
+ {
+ wrap_here ("");
+ printf_unfiltered (_("(no debugging symbols found)..."));
+ wrap_here ("");
+ }
+
+ printf_unfiltered (_("done.\n"));
+ }
+ }
+ }
+
+ return objfile;
+}
+
+/* Traverse all psymtabs in one objfile, requiring that the psymtabs
+ be read in. */
+
+#define ALL_OBJFILE_PSYMTABS_REQUIRED(objfile, p) \
+ for ((p) = require_partial_symbols (objfile, 1)->psymtabs; \
+ (p) != NULL; \
+ (p) = (p)->next)
+
+/* We want to make sure this file always requires psymtabs. */
+
+#undef ALL_OBJFILE_PSYMTABS
+
+/* Traverse all psymtabs in all objfiles. */
+
+#define ALL_PSYMTABS(objfile, p) \
+ ALL_OBJFILES (objfile) \
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
+
+/* Helper function for partial_map_symtabs_matching_filename that
+ expands the symtabs and calls the iterator. */
+
+static int
+partial_map_expand_apply (struct objfile *objfile,
+ const char *name,
+ const char *full_path,
+ const char *real_path,
+ struct partial_symtab *pst,
+ int (*callback) (struct symtab *, void *),
+ void *data)
+{
+ struct symtab *last_made = objfile->symtabs;
+
+ /* Don't visit already-expanded psymtabs. */
+ if (pst->readin)
+ return 0;
+
+ /* This may expand more than one symtab, and we want to iterate over
+ all of them. */
+ psymtab_to_symtab (pst);
+
+ return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ objfile->symtabs, last_made);
+}
+
+/* Implementation of the map_symtabs_matching_filename method. */
+
+static int
+partial_map_symtabs_matching_filename (struct objfile *objfile,
+ const char *name,
+ const char *full_path,
+ const char *real_path,
+ int (*callback) (struct symtab *,
+ void *),
+ void *data)
{
struct partial_symtab *pst;
+ const char *name_basename = lbasename (name);
+ int name_len = strlen (name);
+ int is_abs = IS_ABSOLUTE_PATH (name);
- ALL_OBJFILE_PSYMTABS (objfile, pst)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
- if (FILENAME_CMP (name, pst->filename) == 0)
+ if (FILENAME_CMP (name, pst->filename) == 0
+ || (!is_abs && compare_filenames_for_search (pst->filename,
+ name, name_len)))
{
- return (pst);
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (name_basename, lbasename (pst->filename)) != 0)
+ continue;
+
/* If the user gave us an absolute path, try to find the file in
this symtab and use its absolute path. */
if (full_path != NULL)
{
psymtab_to_fullname (pst);
if (pst->fullname != NULL
- && FILENAME_CMP (full_path, pst->fullname) == 0)
+ && (FILENAME_CMP (full_path, pst->fullname) == 0
+ || (!is_abs && compare_filenames_for_search (pst->fullname,
+ name, name_len))))
{
- return pst;
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
}
rp = gdb_realpath (pst->fullname);
make_cleanup (xfree, rp);
}
- if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
+ if (rp != NULL
+ && (FILENAME_CMP (real_path, rp) == 0
+ || (!is_abs && compare_filenames_for_search (real_path,
+ name, name_len))))
{
- return pst;
+ if (partial_map_expand_apply (objfile, name, full_path, real_path,
+ pst, callback, data))
+ return 1;
}
}
}
- /* Now, search for a matching tail (only if name doesn't have any dirs) */
-
- if (lbasename (name) == name)
- ALL_OBJFILE_PSYMTABS (objfile, pst)
- {
- if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
- return (pst);
- }
-
- return (NULL);
-}
-
-static int
-lookup_symtab_via_partial_symtab (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path,
- struct symtab **result)
-{
- struct partial_symtab *ps;
-
- ps = lookup_partial_symtab (objfile, name, full_path, real_path);
- if (!ps)
- return 0;
-
- if (ps->readin)
- error (_("Internal: readin %s pst for `%s' found when no symtab found."),
- ps->filename, name);
-
- *result = PSYMTAB_TO_SYMTAB (ps);
- return 1;
+ return 0;
}
/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
struct partial_symtab *best_pst = pst;
CORE_ADDR best_addr = pst->textlow;
+ gdb_assert (!pst->psymtabs_addrmap_supported);
+
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
function containing the PC. */
if (!(objfile->flags & OBJF_REORDERED) &&
- section == 0) /* can't validate section this way */
+ section == 0) /* Can't validate section this way. */
return pst;
if (msymbol == NULL)
/* The code range of partial symtabs sometimes overlap, so, in
the loop below, we need to check all partial symtabs and
- find the one that fits better for the given PC address. We
+ find the one that fits better for the given PC address. We
select the partial symtab that contains a symbol whose
address is closest to the PC address. By closest we mean
that find_pc_sect_symbol returns the symbol with address
necessarily lower or equal to PC, the symbol closer
to PC is the symbol which address is the highest.
This way we return the psymtab which contains such
- best match symbol. This can help in cases where the
+ best match symbol. This can help in cases where the
symbol information/debuginfo is not complete, like
for instance on IRIX6 with gcc, where no debug info
- is emitted for statics. (See also the nodebug.exp
- testcase.) */
+ is emitted for statics. (See also the nodebug.exp
+ testcase.) */
if (this_addr > best_addr)
{
best_addr = this_addr;
its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
debug info type in single OBJFILE. */
- ALL_OBJFILE_PSYMTABS (objfile, pst)
- if (pc >= pst->textlow && pc < pst->texthigh)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
+ if (!pst->psymtabs_addrmap_supported
+ && pc >= pst->textlow && pc < pst->texthigh)
{
struct partial_symtab *best_pst;
gdb_assert (psymtab != NULL);
- /* Cope with programs that start at address 0 */
+ /* Cope with programs that start at address 0. */
best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
/* Search the global symbols as well as the static symbols, so that
|| (psymtab->textlow == 0
&& best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
{
- if (section) /* match on a specific section */
+ if (section) /* Match on a specific section. */
{
fixup_psymbol_section (p, psymtab->objfile);
if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
|| (psymtab->textlow == 0
&& best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
{
- if (section) /* match on a specific section */
+ if (section) /* Match on a specific section. */
{
fixup_psymbol_section (p, psymtab->objfile);
if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
struct partial_symtab *ps;
const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain))
- return PSYMTAB_TO_SYMTAB (ps);
+ {
+ struct symbol *sym = NULL;
+ struct symtab *stab = PSYMTAB_TO_SYMTAB (ps);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the psymtab will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+
+ sym = lookup_block_symbol (block, name, domain);
+ }
+
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ return stab;
+
+ /* Keep looking through other psymtabs. */
+ }
}
return NULL;
}
+/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
+ the global block of PST if GLOBAL, and otherwise the static block.
+ MATCH is the comparison operation that returns true iff MATCH (s,
+ NAME), where s is a SYMBOL_SEARCH_NAME. If ORDERED_COMPARE is
+ non-null, the symbols in the block are assumed to be ordered
+ according to it (allowing binary search). It must be compatible
+ with MATCH. Returns the symbol, if found, and otherwise NULL. */
+
+static struct partial_symbol *
+match_partial_symbol (struct partial_symtab *pst, int global,
+ const char *name, domain_enum domain,
+ symbol_compare_ftype *match,
+ symbol_compare_ftype *ordered_compare)
+{
+ struct partial_symbol **start, **psym;
+ struct partial_symbol **top, **real_top, **bottom, **center;
+ int length = (global ? pst->n_global_syms : pst->n_static_syms);
+ int do_linear_search = 1;
+
+ if (length == 0)
+ return NULL;
+ start = (global ?
+ pst->objfile->global_psymbols.list + pst->globals_offset :
+ pst->objfile->static_psymbols.list + pst->statics_offset);
+
+ if (global && ordered_compare) /* Can use a binary search. */
+ {
+ do_linear_search = 0;
+
+ /* Binary search. This search is guaranteed to end with center
+ pointing at the earliest partial symbol whose name might be
+ correct. At that point *all* partial symbols with an
+ appropriate name will be checked against the correct
+ domain. */
+
+ bottom = start;
+ top = start + length - 1;
+ real_top = top;
+ while (top > bottom)
+ {
+ center = bottom + (top - bottom) / 2;
+ gdb_assert (center < top);
+ if (!do_linear_search
+ && (SYMBOL_LANGUAGE (*center) == language_java))
+ do_linear_search = 1;
+ if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+ top = center;
+ else
+ bottom = center + 1;
+ }
+ gdb_assert (top == bottom);
+
+ while (top <= real_top
+ && match (SYMBOL_SEARCH_NAME (*top), name) == 0)
+ {
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+ SYMBOL_DOMAIN (*top), domain))
+ return *top;
+ top++;
+ }
+ }
+
+ /* Can't use a binary search or else we found during the binary search that
+ we should also do a linear search. */
+
+ if (do_linear_search)
+ {
+ for (psym = start; psym < start + length; psym++)
+ {
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+ SYMBOL_DOMAIN (*psym), domain)
+ && match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
+ return *psym;
+ }
+ }
+
+ return NULL;
+}
+
static void
pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
- int kind, const char *name,
+ enum block_enum block_kind,
+ const char *name,
domain_enum domain)
{
/* Nothing. */
}
+/* Returns the name used to search psymtabs. Unlike symtabs, psymtabs do
+ not contain any method/function instance information (since this would
+ force reading type information while reading psymtabs). Therefore,
+ if NAME contains overload information, it must be stripped before searching
+ psymtabs.
+
+ The caller is responsible for freeing the return result. */
+
+static char *
+psymtab_search_name (const char *name)
+{
+ switch (current_language->la_language)
+ {
+ case language_cplus:
+ case language_java:
+ {
+ if (strchr (name, '('))
+ {
+ char *ret = cp_remove_params (name);
+
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return xstrdup (name);
+}
+
/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
- Check the global symbols if GLOBAL, the static symbols if not. */
+ Check the global symbols if GLOBAL, the static symbols if not. */
static struct partial_symbol *
lookup_partial_symbol (struct partial_symtab *pst, const char *name,
struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
+ char *search_name;
+ struct cleanup *cleanup;
if (length == 0)
{
return (NULL);
}
+
+ search_name = psymtab_search_name (name);
+ cleanup = make_cleanup (xfree, search_name);
start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
- if (global) /* This means we can use a binary search. */
+ if (global) /* This means we can use a binary search. */
{
do_linear_search = 0;
{
center = bottom + (top - bottom) / 2;
if (!(center < top))
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
if (!do_linear_search
- && (SYMBOL_LANGUAGE (*center) == language_java))
+ && SYMBOL_LANGUAGE (*center) == language_java)
{
do_linear_search = 1;
}
- if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
+ search_name) >= 0)
{
top = center;
}
}
}
if (!(top == bottom))
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
- while (top <= real_top
- && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
+ /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
+ search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME. */
+ while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
+ top--;
+
+ /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME. */
+ top++;
+
+ while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
SYMBOL_DOMAIN (*top), domain))
- return (*top);
+ {
+ do_cleanups (cleanup);
+ return (*top);
+ }
top++;
}
}
/* Can't use a binary search or else we found during the binary search that
- we should also do a linear search. */
+ we should also do a linear search. */
if (do_linear_search)
{
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
SYMBOL_DOMAIN (*psym), domain)
- && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
- return (*psym);
+ && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
+ {
+ do_cleanups (cleanup);
+ return (*psym);
+ }
}
}
+ do_cleanups (cleanup);
return (NULL);
}
static struct symtab *
psymtab_to_symtab (struct partial_symtab *pst)
{
- /* If it's been looked up before, return it. */
+ /* If it's been looked up before, return it. */
if (pst->symtab)
return pst->symtab;
struct partial_symbol **psym;
struct partial_symtab *p;
- ALL_OBJFILE_PSYMTABS (objfile, p)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
{
p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
struct partial_symtab *ps;
struct partial_symtab *cs_pst = 0;
- ALL_OBJFILE_PSYMTABS (ofp, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (ofp, ps)
{
const char *name = ps->filename;
int len = strlen (name);
{
struct partial_symtab *pst;
- ALL_OBJFILE_PSYMTABS (objfile, pst)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
if (pst->fullname != NULL)
{
fputs_filtered ("undefined domain, ", outfile);
break;
case VAR_DOMAIN:
- /* This is the usual thing -- don't print it */
+ /* This is the usual thing -- don't print it. */
break;
case STRUCT_DOMAIN:
fputs_filtered ("struct domain, ", outfile);
fprintf_filtered (outfile, "-");
fputs_filtered (paddress (gdbarch, psymtab->texthigh), outfile);
fprintf_filtered (outfile, "\n");
+ fprintf_filtered (outfile, " Address map supported - %s.\n",
+ psymtab->psymtabs_addrmap_supported ? "yes" : "no");
fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
psymtab->number_of_dependencies);
for (i = 0; i < psymtab->number_of_dependencies; i++)
struct partial_symtab *ps;
i = 0;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
if (ps->readin == 0)
i++;
}
/* Look through the partial symtabs for all symbols which begin
- by matching FUNC_NAME. Make sure we read that symbol table in. */
+ by matching FUNC_NAME. Make sure we read that symbol table in. */
static void
read_symtabs_for_function (struct objfile *objfile, const char *func_name)
{
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
if (ps->readin)
continue;
{
struct partial_symtab *psymtab;
- for (psymtab = objfile->psymtabs;
- psymtab != NULL;
- psymtab = psymtab->next)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
{
psymtab_to_symtab (psymtab);
}
{
struct partial_symtab *p;
- ALL_OBJFILE_PSYMTABS (objfile, p)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
{
- if (strcmp (filename, p->filename) == 0)
+ if (filename_cmp (filename, p->filename) == 0)
PSYMTAB_TO_SYMTAB (p);
}
}
-static void
-map_symbol_names_psymtab (struct objfile *objfile,
- void (*fun) (const char *, void *), void *data)
-{
- struct partial_symtab *ps;
-
- ALL_OBJFILE_PSYMTABS (objfile, ps)
- {
- struct partial_symbol **psym;
-
- /* If the psymtab's been read in we'll get it when we search
- through the blockvector. */
- if (ps->readin)
- continue;
-
- for (psym = objfile->global_psymbols.list + ps->globals_offset;
- psym < (objfile->global_psymbols.list + ps->globals_offset
- + ps->n_global_syms);
- psym++)
- {
- /* If interrupted, then quit. */
- QUIT;
- (*fun) (SYMBOL_NATURAL_NAME (*psym), data);
- }
-
- for (psym = objfile->static_psymbols.list + ps->statics_offset;
- psym < (objfile->static_psymbols.list + ps->statics_offset
- + ps->n_static_syms);
- psym++)
- {
- QUIT;
- (*fun) (SYMBOL_NATURAL_NAME (*psym), data);
- }
- }
-}
-
static void
map_symbol_filenames_psymtab (struct objfile *objfile,
- void (*fun) (const char *, const char *,
- void *),
- void *data)
+ symbol_filename_ftype *fun, void *data,
+ int need_fullname)
{
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
const char *fullname;
if (ps->readin)
continue;
- fullname = psymtab_to_fullname (ps);
+ QUIT;
+ if (need_fullname)
+ fullname = psymtab_to_fullname (ps);
+ else
+ fullname = NULL;
(*fun) (ps->filename, fullname, data);
}
}
If this function fails to find the file that this partial_symtab represents,
NULL will be returned and ps->fullname will be set to NULL. */
+
static char *
psymtab_to_fullname (struct partial_symtab *ps)
{
if (!ps)
return NULL;
- /* Don't check ps->fullname here, the file could have been
- deleted/moved/..., look for it again */
+ /* Use cached copy if we have it.
+ We rely on forget_cached_source_info being called appropriately
+ to handle cases like the file being moved. */
+ if (ps->fullname)
+ return ps->fullname;
+
r = find_and_open_source (ps->filename, ps->dirname, &ps->fullname);
if (r >= 0)
{
struct partial_symtab *pst;
- ALL_OBJFILE_PSYMTABS (objfile, pst)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
if (lookup_partial_symbol (pst, name, 1, VAR_DOMAIN))
return pst->filename;
return NULL;
}
-/* Look, in partial_symtab PST, for symbol NAME in given namespace.
- Check the global symbols if GLOBAL, the static symbols if not.
- Do wild-card match if WILD. */
+/* For all symbols, s, in BLOCK that are in NAMESPACE and match NAME
+ according to the function MATCH, call CALLBACK(BLOCK, s, DATA).
+ BLOCK is assumed to come from OBJFILE. Returns 1 iff CALLBACK
+ ever returns non-zero, and otherwise returns 0. */
-static struct partial_symbol *
-ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
- int global, domain_enum namespace, int wild,
- int (*wild_match) (const char *, int, const char *),
- int (*is_name_suffix) (const char *))
+static int
+map_block (const char *name, domain_enum namespace, struct objfile *objfile,
+ struct block *block,
+ int (*callback) (struct block *, struct symbol *, void *),
+ void *data, symbol_compare_ftype *match)
{
- struct partial_symbol **start;
- int name_len = strlen (name);
- int length = (global ? pst->n_global_syms : pst->n_static_syms);
- int i;
+ struct dict_iterator iter;
+ struct symbol *sym;
- if (length == 0)
+ for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter);
+ sym != NULL; sym = dict_iter_match_next (name, match, &iter))
{
- return (NULL);
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), namespace))
+ {
+ if (callback (block, sym, data))
+ return 1;
+ }
}
- start = (global ?
- pst->objfile->global_psymbols.list + pst->globals_offset :
- pst->objfile->static_psymbols.list + pst->statics_offset);
-
- if (wild)
- {
- for (i = 0; i < length; i += 1)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace)
- && (*wild_match) (name, name_len, SYMBOL_LINKAGE_NAME (psym)))
- return psym;
- }
- return NULL;
- }
- else
- {
- if (global)
- {
- int U;
-
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
-
- if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
-
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace))
- {
- int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
-
- if (cmp < 0)
- {
- if (global)
- break;
- }
- else if (cmp == 0
- && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
- + name_len))
- return psym;
- }
- i += 1;
- }
-
- if (global)
- {
- int U;
-
- i = 0;
- U = length - 1;
- while (U - i > 4)
- {
- int M = (U + i) >> 1;
- struct partial_symbol *psym = start[M];
-
- if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
- i = M + 1;
- else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
- U = M - 1;
- else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0)
- i = M + 1;
- else
- U = M;
- }
- }
- else
- i = 0;
-
- while (i < length)
- {
- struct partial_symbol *psym = start[i];
-
- if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
- SYMBOL_DOMAIN (psym), namespace))
- {
- int cmp;
-
- cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0];
- if (cmp == 0)
- {
- cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5);
- if (cmp == 0)
- cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5,
- name_len);
- }
-
- if (cmp < 0)
- {
- if (global)
- break;
- }
- else if (cmp == 0
- && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
- + name_len + 5))
- return psym;
- }
- i += 1;
- }
- }
- return NULL;
+ return 0;
}
+/* Psymtab version of map_matching_symbols. See its definition in
+ the definition of quick_symbol_functions in symfile.h. */
+
static void
-map_ada_symtabs (struct objfile *objfile,
- int (*wild_match) (const char *, int, const char *),
- int (*is_name_suffix) (const char *),
- void (*callback) (struct objfile *, struct symtab *, void *),
- const char *name, int global, domain_enum namespace, int wild,
- void *data)
+map_matching_symbols_psymtab (const char *name, domain_enum namespace,
+ struct objfile *objfile, int global,
+ int (*callback) (struct block *,
+ struct symbol *, void *),
+ void *data,
+ symbol_compare_ftype *match,
+ symbol_compare_ftype *ordered_compare)
{
+ const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
QUIT;
if (ps->readin
- || ada_lookup_partial_symbol (ps, name, global, namespace, wild,
- wild_match, is_name_suffix))
+ || match_partial_symbol (ps, global, name, namespace, match,
+ ordered_compare))
{
struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
+ struct block *block;
if (s == NULL || !s->primary)
continue;
- (*callback) (objfile, s, data);
+ block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind);
+ if (map_block (name, namespace, objfile, block,
+ callback, data, match))
+ return;
+ if (callback (block, NULL, data))
+ return;
}
}
-}
+}
static void
-expand_symtabs_matching_via_partial (struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const char *, void *),
- domain_enum kind,
- void *data)
+expand_symtabs_matching_via_partial
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const char *, void *),
+ enum search_domain kind,
+ void *data)
{
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
struct partial_symbol **psym;
struct partial_symbol **bound, **gbound, **sbound;
if (ps->readin)
continue;
- if (! (*file_matcher) (ps->filename, data))
+ if (file_matcher && ! (*file_matcher) (ps->filename, data))
continue;
- gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms;
- sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms;
+ gbound = objfile->global_psymbols.list
+ + ps->globals_offset + ps->n_global_syms;
+ sbound = objfile->static_psymbols.list
+ + ps->statics_offset + ps->n_static_syms;
bound = gbound;
/* Go through all of the symbols stored in a partial
- symtab in one loop. */
+ symtab in one loop. */
psym = objfile->global_psymbols.list + ps->globals_offset;
while (keep_going)
{
{
QUIT;
- if ((*name_matcher) (SYMBOL_NATURAL_NAME (*psym), data)
- && ((kind == VARIABLES_DOMAIN
+ if ((kind == ALL_DOMAIN
+ || (kind == VARIABLES_DOMAIN
&& SYMBOL_CLASS (*psym) != LOC_TYPEDEF
&& SYMBOL_CLASS (*psym) != LOC_BLOCK)
- || (kind == FUNCTIONS_DOMAIN
- && SYMBOL_CLASS (*psym) == LOC_BLOCK)
- || (kind == TYPES_DOMAIN
- && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)))
+ || (kind == FUNCTIONS_DOMAIN
+ && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN
+ && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
+ && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
{
PSYMTAB_TO_SYMTAB (ps);
keep_going = 0;
objfile_has_psyms,
find_last_source_symtab_from_partial,
forget_cached_source_info_partial,
- lookup_symtab_via_partial_symtab,
+ partial_map_symtabs_matching_filename,
lookup_symbol_aux_psymtabs,
pre_expand_symtabs_matching_psymtabs,
print_psymtab_stats_for_objfile,
expand_partial_symbol_tables,
read_psymtabs_with_filename,
find_symbol_file_from_partial,
- map_ada_symtabs,
+ map_matching_symbols_psymtab,
expand_symtabs_matching_via_partial,
find_pc_sect_symtab_from_partial,
- map_symbol_names_psymtab,
map_symbol_filenames_psymtab
};
void
sort_pst_symbols (struct partial_symtab *pst)
{
- /* Sort the global list; don't sort the static list */
+ /* Sort the global list; don't sort the static list. */
qsort (pst->objfile->global_psymbols.list + pst->globals_offset,
pst->n_global_syms, sizeof (struct partial_symbol *),
/* Allocate and partially fill a partial symtab. It will be
completely filled at the end of the symbol list.
- FILENAME is the name of the symbol-file we are reading from. */
+ FILENAME is the name of the symbol-file we are reading from. */
struct partial_symtab *
start_psymtab_common (struct objfile *objfile,
/* Calculate a hash code for the given partial symbol. The hash is
calculated using the symbol's value, language, domain, class
- and name. These are the values which are set by
+ and name. These are the values which are set by
add_psymbol_to_bcache. */
static unsigned long
xfree (bcache);
}
-/* Return the internal bcache of the psymbol_bcache BCACHE*/
+/* Return the internal bcache of the psymbol_bcache BCACHE. */
struct bcache *
psymbol_bcache_get_bcache (struct psymbol_bcache *bcache)
different domain (or address) is possible and correct. */
static const struct partial_symbol *
-add_psymbol_to_bcache (char *name, int namelength, int copy_name,
+add_psymbol_to_bcache (const char *name, int namelength, int copy_name,
domain_enum domain,
enum address_class class,
long val, /* Value as a long */
entire field. */
memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value));
- /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+ /* val and coreaddr are mutually exclusive, one of them *will* be zero. */
if (val != 0)
{
SYMBOL_VALUE (&psymbol) = val;
SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
- /* Stash the partial symbol away in the cache */
+ /* Stash the partial symbol away in the cache. */
return psymbol_bcache_full (&psymbol,
objfile->psymbol_cache,
added);
}
/* Increase the space allocated for LISTP, which is probably
- global_psymbols or static_psymbols. This space will eventually
+ global_psymbols or static_psymbols. This space will eventually
be freed in free_objfile(). */
static void
new_size * sizeof (struct partial_symbol *));
}
/* Next assumes we only went one over. Should be good if
- program works correctly */
+ program works correctly. */
listp->next = listp->list + listp->size;
listp->size = new_size;
}
cache. */
const struct partial_symbol *
-add_psymbol_to_list (char *name, int namelength, int copy_name,
+add_psymbol_to_list (const char *name, int namelength, int copy_name,
domain_enum domain,
enum address_class class,
struct psymbol_allocation_list *list,
int added;
- /* Stash the partial symbol away in the cache */
+ /* Stash the partial symbol away in the cache. */
psym = add_psymbol_to_bcache (name, namelength, copy_name, domain, class,
val, coreaddr, language, objfile, &added);
&& !added)
return psym;
- /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+ /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
append_psymbol_to_list (list, psym, objfile);
return psym;
}
/* Current best guess is that approximately a twentieth
of the total symbols (in a debugging file) are global or static
- oriented symbols */
+ oriented symbols. */
objfile->global_psymbols.size = total_symbols / 10;
objfile->static_psymbols.size = total_symbols / 10;
/* Prepend it to the psymtab list for the objfile it belongs to.
Psymtabs are searched in most recent inserted -> least recent
- inserted order. */
+ inserted order. */
psymtab->objfile = objfile;
psymtab->next = objfile->psymtabs;
nothing else is not empty, but we don't realize that. Fixing
that without slowing things down might be tricky. */
- /* First, snip it out of the psymtab chain */
+ /* First, snip it out of the psymtab chain. */
prev_pst = &(pst->objfile->psymtabs);
while ((*prev_pst) != pst)
prev_pst = &((*prev_pst)->next);
(*prev_pst) = pst->next;
- /* Next, put it on a free list for recycling */
+ /* Next, put it on a free list for recycling. */
pst->next = pst->objfile->free_psymtabs;
pst->objfile->free_psymtabs = pst;
if (args == NULL)
{
- error (_("print-psymbols takes an output file name and optional symbol file name"));
+ error (_("\
+print-psymbols takes an output file name and optional symbol file name"));
}
argv = gdb_buildargv (args);
cleanups = make_cleanup_freeargv (argv);
if (argv[0] != NULL)
{
filename = argv[0];
- /* If a second arg is supplied, it is a source file name to match on */
+ /* If a second arg is supplied, it is a source file name to match on. */
if (argv[1] != NULL)
{
symname = argv[1];
immediate_quit++;
ALL_PSYMTABS (objfile, ps)
- if (symname == NULL || strcmp (symname, ps->filename) == 0)
+ if (symname == NULL || filename_cmp (symname, ps->filename) == 0)
dump_psymtab (objfile, ps, outfile);
immediate_quit--;
do_cleanups (cleanups);
actually find a symtab whose name matches. */
int printed_objfile_start = 0;
- ALL_OBJFILE_PSYMTABS (objfile, psymtab)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
{
QUIT;
printf_filtered (" readin %s\n",
psymtab->readin ? "yes" : "no");
printf_filtered (" fullname %s\n",
- psymtab->fullname ? psymtab->fullname : "(null)");
+ psymtab->fullname
+ ? psymtab->fullname : "(null)");
printf_filtered (" text addresses ");
fputs_filtered (paddress (gdbarch, psymtab->textlow),
gdb_stdout);
fputs_filtered (paddress (gdbarch, psymtab->texthigh),
gdb_stdout);
printf_filtered ("\n");
+ printf_filtered (" psymtabs_addrmap_supported %s\n",
+ (psymtab->psymtabs_addrmap_supported
+ ? "yes" : "no"));
printf_filtered (" globals ");
if (psymtab->n_global_syms)
{
\f
void
-map_partial_symbol_names (void (*fun) (const char *, void *), void *data)
+expand_partial_symbol_names (int (*fun) (const char *, void *),
+ void *data)
{
struct objfile *objfile;
ALL_OBJFILES (objfile)
{
if (objfile->sf)
- objfile->sf->qf->map_symbol_names (objfile, fun, data);
+ objfile->sf->qf->expand_symtabs_matching (objfile, NULL, fun,
+ ALL_DOMAIN, data);
}
}
void
-map_partial_symbol_filenames (void (*fun) (const char *, const char *,
- void *),
- void *data)
+map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
+ int need_fullname)
{
struct objfile *objfile;
ALL_OBJFILES (objfile)
{
if (objfile->sf)
- objfile->sf->qf->map_symbol_filenames (objfile, fun, data);
+ objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
+ need_fullname);
}
}