#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"
static struct symtab *psymtab_to_symtab (struct partial_symtab *pst);
+/* Ensure that the partial symbols for OBJFILE have been loaded. This
+ function always returns its argument, as a convenience. */
+
+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)
+
/* 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. */
{
struct partial_symtab *pst;
- ALL_OBJFILE_PSYMTABS (objfile, pst)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
if (FILENAME_CMP (name, pst->filename) == 0)
{
}
}
- /* Now, search for a matching tail (only if name doesn't have any dirs) */
+ /* Now, search for a matching tail (only if name doesn't have any dirs). */
if (lbasename (name) == name)
- ALL_OBJFILE_PSYMTABS (objfile, pst)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
{
if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
return (pst);
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)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
if (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;
/* 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. */
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)
{
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))
+ && 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++;
}
}
{
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);
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);
}
}
{
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
struct partial_symbol **psym;
+ ps->n_global_syms);
psym++)
{
- /* If interrupted, then quit. */
+ /* If interrupted, then quit. */
QUIT;
(*fun) (SYMBOL_NATURAL_NAME (*psym), data);
}
{
struct partial_symtab *ps;
- ALL_OBJFILE_PSYMTABS (objfile, ps)
+ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
{
const char *fullname;
return NULL;
/* Don't check ps->fullname here, the file could have been
- deleted/moved/..., look for it again */
+ deleted/moved/..., look for it again. */
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;
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
static void
expand_symtabs_matching_via_partial (struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const char *, void *),
+ int (*file_matcher) (const char *,
+ void *),
+ int (*name_matcher) (const char *,
+ void *),
domain_enum 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 (! (*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)
{
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)
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;
}
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);