| Index: gdb/psymtab.c
|
| diff --git a/gdb/psymtab.c b/gdb/psymtab.c
|
| index d5cfa8b22f09f67207142948ef8faa29f8b363cb..5623e2dc5f8ba30d6b1aa52cb6c9fa3579855d70 100644
|
| --- a/gdb/psymtab.c
|
| +++ b/gdb/psymtab.c
|
| @@ -45,10 +45,6 @@ struct psymbol_bcache
|
| struct bcache *bcache;
|
| };
|
|
|
| -/* A fast way to get from a psymtab to its symtab (after the first time). */
|
| -#define PSYMTAB_TO_SYMTAB(pst) \
|
| - ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
|
| -
|
| static struct partial_symbol *match_partial_symbol (struct partial_symtab *,
|
| int,
|
| const char *, domain_enum,
|
| @@ -139,6 +135,10 @@ partial_map_expand_apply (struct objfile *objfile,
|
| {
|
| struct symtab *last_made = objfile->symtabs;
|
|
|
| + /* Shared psymtabs should never be seen here. Instead they should
|
| + be handled properly by the caller. */
|
| + gdb_assert (pst->user == NULL);
|
| +
|
| /* Don't visit already-expanded psymtabs. */
|
| if (pst->readin)
|
| return 0;
|
| @@ -164,10 +164,23 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
| {
|
| 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_REQUIRED (objfile, pst)
|
| {
|
| - if (FILENAME_CMP (name, pst->filename) == 0)
|
| + /* We can skip shared psymtabs here, because any file name will be
|
| + attached to the unshared psymtab. */
|
| + if (pst->user != NULL)
|
| + continue;
|
| +
|
| + /* Anonymous psymtabs don't have a file name. */
|
| + if (pst->anonymous)
|
| + continue;
|
| +
|
| + if (FILENAME_CMP (name, pst->filename) == 0
|
| + || (!is_abs && compare_filenames_for_search (pst->filename,
|
| + name, name_len)))
|
| {
|
| if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
| pst, callback, data))
|
| @@ -186,7 +199,9 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
| {
|
| 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))))
|
| {
|
| if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
| pst, callback, data))
|
| @@ -203,7 +218,10 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
| 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))))
|
| {
|
| if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
| pst, callback, data))
|
| @@ -212,17 +230,6 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
| }
|
| }
|
|
|
| - /* Now, search for a matching tail (only if name doesn't have any dirs). */
|
| -
|
| - if (name_basename == name)
|
| - ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
|
| - {
|
| - if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
|
| - if (partial_map_expand_apply (objfile, name, full_path, real_path, pst,
|
| - callback, data))
|
| - return 1;
|
| - }
|
| -
|
| return 0;
|
| }
|
|
|
| @@ -394,7 +401,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile,
|
| warning (_("\
|
| (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
|
| paddress (get_objfile_arch (ps->objfile), pc));
|
| - return PSYMTAB_TO_SYMTAB (ps);
|
| + psymtab_to_symtab (ps);
|
| + return ps->symtab;
|
| }
|
| return NULL;
|
| }
|
| @@ -506,13 +514,14 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
|
| {
|
| struct partial_symtab *ps;
|
| const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
|
| + struct symtab *stab_best = NULL;
|
|
|
| ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
| {
|
| if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain))
|
| {
|
| struct symbol *sym = NULL;
|
| - struct symtab *stab = PSYMTAB_TO_SYMTAB (ps);
|
| + 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
|
| @@ -526,13 +535,18 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
|
| }
|
|
|
| if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
| - return stab;
|
| + {
|
| + if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
| + return stab;
|
| +
|
| + stab_best = stab;
|
| + }
|
|
|
| /* Keep looking through other psymtabs. */
|
| }
|
| }
|
|
|
| - return NULL;
|
| + return stab_best;
|
| }
|
|
|
| /* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
|
| @@ -761,13 +775,16 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
|
| }
|
|
|
| /* Get the symbol table that corresponds to a partial_symtab.
|
| - This is fast after the first time you do it. In fact, there
|
| - is an even faster macro PSYMTAB_TO_SYMTAB that does the fast
|
| - case inline. */
|
| + This is fast after the first time you do it. */
|
|
|
| static struct symtab *
|
| psymtab_to_symtab (struct partial_symtab *pst)
|
| {
|
| + /* If it is a shared psymtab, find an unshared psymtab that includes
|
| + it. Any such psymtab will do. */
|
| + while (pst->user != NULL)
|
| + pst = pst->user;
|
| +
|
| /* If it's been looked up before, return it. */
|
| if (pst->symtab)
|
| return pst->symtab;
|
| @@ -843,7 +860,7 @@ find_last_source_symtab_from_partial (struct objfile *ofp)
|
| "readin pst found and no symtabs."));
|
| }
|
| else
|
| - return PSYMTAB_TO_SYMTAB (cs_pst);
|
| + return psymtab_to_symtab (cs_pst);
|
| }
|
| return NULL;
|
| }
|
| @@ -960,8 +977,16 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
|
| struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
| int i;
|
|
|
| - fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
|
| - psymtab->filename);
|
| + if (psymtab->anonymous)
|
| + {
|
| + fprintf_filtered (outfile, "\nAnonymous partial symtab (%s) ",
|
| + psymtab->filename);
|
| + }
|
| + else
|
| + {
|
| + fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
|
| + psymtab->filename);
|
| + }
|
| fprintf_filtered (outfile, "(object ");
|
| gdb_print_host_address (psymtab, outfile);
|
| fprintf_filtered (outfile, ")\n\n");
|
| @@ -1008,6 +1033,12 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
|
| fprintf_filtered (outfile, " %s\n",
|
| psymtab->dependencies[i]->filename);
|
| }
|
| + if (psymtab->user != NULL)
|
| + {
|
| + fprintf_filtered (outfile, " Shared partial symtab with user ");
|
| + gdb_print_host_address (psymtab->user, outfile);
|
| + fprintf_filtered (outfile, "\n");
|
| + }
|
| if (psymtab->n_global_syms > 0)
|
| {
|
| print_partial_symbols (gdbarch,
|
| @@ -1105,8 +1136,12 @@ read_psymtabs_with_filename (struct objfile *objfile, const char *filename)
|
|
|
| ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
|
| {
|
| + /* Anonymous psymtabs don't have a name of a source file. */
|
| + if (p->anonymous)
|
| + continue;
|
| +
|
| if (filename_cmp (filename, p->filename) == 0)
|
| - PSYMTAB_TO_SYMTAB (p);
|
| + psymtab_to_symtab (p);
|
| }
|
| }
|
|
|
| @@ -1124,6 +1159,15 @@ map_symbol_filenames_psymtab (struct objfile *objfile,
|
| if (ps->readin)
|
| continue;
|
|
|
| + /* We can skip shared psymtabs here, because any file name will be
|
| + attached to the unshared psymtab. */
|
| + if (ps->user != NULL)
|
| + continue;
|
| +
|
| + /* Anonymous psymtabs don't have a file name. */
|
| + if (ps->anonymous)
|
| + continue;
|
| +
|
| QUIT;
|
| if (need_fullname)
|
| fullname = psymtab_to_fullname (ps);
|
| @@ -1133,10 +1177,6 @@ map_symbol_filenames_psymtab (struct objfile *objfile,
|
| }
|
| }
|
|
|
| -int find_and_open_source (const char *filename,
|
| - const char *dirname,
|
| - char **fullname);
|
| -
|
| /* Finds the fullname that a partial_symtab represents.
|
|
|
| If this functions finds the fullname, it will save it in ps->fullname
|
| @@ -1152,6 +1192,8 @@ psymtab_to_fullname (struct partial_symtab *ps)
|
|
|
| if (!ps)
|
| return NULL;
|
| + if (ps->anonymous)
|
| + return NULL;
|
|
|
| /* Use cached copy if we have it.
|
| We rely on forget_cached_source_info being called appropriately
|
| @@ -1194,11 +1236,11 @@ map_block (const char *name, domain_enum namespace, struct objfile *objfile,
|
| int (*callback) (struct block *, struct symbol *, void *),
|
| void *data, symbol_compare_ftype *match)
|
| {
|
| - struct dict_iterator iter;
|
| + struct block_iterator iter;
|
| struct symbol *sym;
|
|
|
| - for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter);
|
| - sym != NULL; sym = dict_iter_match_next (name, match, &iter))
|
| + for (sym = block_iter_match_first (block, name, match, &iter);
|
| + sym != NULL; sym = block_iter_match_next (name, match, &iter))
|
| {
|
| if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
| SYMBOL_DOMAIN (sym), namespace))
|
| @@ -1233,7 +1275,7 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
|
| || match_partial_symbol (ps, global, name, namespace, match,
|
| ordered_compare))
|
| {
|
| - struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
|
| + struct symtab *s = psymtab_to_symtab (ps);
|
| struct block *block;
|
|
|
| if (s == NULL || !s->primary)
|
| @@ -1248,71 +1290,130 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
|
| }
|
| }
|
|
|
| +/* A helper for expand_symtabs_matching_via_partial that handles
|
| + searching included psymtabs. This returns 1 if a symbol is found,
|
| + and zero otherwise. It also updates the 'searched_flag' on the
|
| + various psymtabs that it searches. */
|
| +
|
| +static int
|
| +recursively_search_psymtabs (struct partial_symtab *ps,
|
| + struct objfile *objfile,
|
| + enum search_domain kind,
|
| + int (*name_matcher) (const char *, void *),
|
| + void *data)
|
| +{
|
| + struct partial_symbol **psym;
|
| + struct partial_symbol **bound, **gbound, **sbound;
|
| + int keep_going = 1;
|
| + int result = PST_SEARCHED_AND_NOT_FOUND;
|
| + int i;
|
| +
|
| + if (ps->searched_flag != PST_NOT_SEARCHED)
|
| + return ps->searched_flag == PST_SEARCHED_AND_FOUND;
|
| +
|
| + /* Recurse into shared psymtabs first, because they may have already
|
| + been searched, and this could save some time. */
|
| + for (i = 0; i < ps->number_of_dependencies; ++i)
|
| + {
|
| + int r;
|
| +
|
| + /* Skip non-shared dependencies, these are handled elsewhere. */
|
| + if (ps->dependencies[i]->user == NULL)
|
| + continue;
|
| +
|
| + r = recursively_search_psymtabs (ps->dependencies[i],
|
| + objfile, kind, name_matcher, data);
|
| + if (r != 0)
|
| + {
|
| + ps->searched_flag = PST_SEARCHED_AND_FOUND;
|
| + return 1;
|
| + }
|
| + }
|
| +
|
| + 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. */
|
| + psym = objfile->global_psymbols.list + ps->globals_offset;
|
| + while (keep_going)
|
| + {
|
| + if (psym >= bound)
|
| + {
|
| + if (bound == gbound && ps->n_static_syms != 0)
|
| + {
|
| + psym = objfile->static_psymbols.list + ps->statics_offset;
|
| + bound = sbound;
|
| + }
|
| + else
|
| + keep_going = 0;
|
| + continue;
|
| + }
|
| + else
|
| + {
|
| + QUIT;
|
| +
|
| + 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))
|
| + && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
|
| + {
|
| + /* Found a match, so notify our caller. */
|
| + result = PST_SEARCHED_AND_FOUND;
|
| + keep_going = 0;
|
| + }
|
| + }
|
| + psym++;
|
| + }
|
| +
|
| + ps->searched_flag = result;
|
| + return result == PST_SEARCHED_AND_FOUND;
|
| +}
|
| +
|
| static void
|
| expand_symtabs_matching_via_partial
|
| (struct objfile *objfile,
|
| int (*file_matcher) (const char *, void *),
|
| - int (*name_matcher) (const struct language_defn *, const char *, void *),
|
| + int (*name_matcher) (const char *, void *),
|
| enum search_domain kind,
|
| void *data)
|
| {
|
| struct partial_symtab *ps;
|
|
|
| + /* Clear the search flags. */
|
| ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
| {
|
| - struct partial_symbol **psym;
|
| - struct partial_symbol **bound, **gbound, **sbound;
|
| - int keep_going = 1;
|
| + ps->searched_flag = PST_NOT_SEARCHED;
|
| + }
|
|
|
| + ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
| + {
|
| if (ps->readin)
|
| continue;
|
|
|
| - if (file_matcher && ! (*file_matcher) (ps->filename, data))
|
| + /* We skip shared psymtabs because file-matching doesn't apply
|
| + to them; but we search them later in the loop. */
|
| + if (ps->user != NULL)
|
| 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;
|
| - bound = gbound;
|
| -
|
| - /* Go through all of the symbols stored in a partial
|
| - symtab in one loop. */
|
| - psym = objfile->global_psymbols.list + ps->globals_offset;
|
| - while (keep_going)
|
| + if (file_matcher)
|
| {
|
| - if (psym >= bound)
|
| - {
|
| - if (bound == gbound && ps->n_static_syms != 0)
|
| - {
|
| - psym = objfile->static_psymbols.list + ps->statics_offset;
|
| - bound = sbound;
|
| - }
|
| - else
|
| - keep_going = 0;
|
| - continue;
|
| - }
|
| - else
|
| - {
|
| - QUIT;
|
| -
|
| - 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))
|
| - && (*name_matcher) (current_language,
|
| - SYMBOL_NATURAL_NAME (*psym), data))
|
| - {
|
| - PSYMTAB_TO_SYMTAB (ps);
|
| - keep_going = 0;
|
| - }
|
| - }
|
| - psym++;
|
| + if (ps->anonymous)
|
| + continue;
|
| + if (! (*file_matcher) (ps->filename, data))
|
| + continue;
|
| }
|
| +
|
| + if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
|
| + psymtab_to_symtab (ps);
|
| }
|
| }
|
|
|
| @@ -1569,18 +1670,7 @@ append_psymbol_to_list (struct psymbol_allocation_list *list,
|
| Since one arg is a struct, we pass in a ptr and deref it (sigh).
|
| Return the partial symbol that has been added. */
|
|
|
| -/* NOTE: carlton/2003-09-11: The reason why we return the partial
|
| - symbol is so that callers can get access to the symbol's demangled
|
| - name, which they don't have any cheap way to determine otherwise.
|
| - (Currenly, dwarf2read.c is the only file who uses that information,
|
| - though it's possible that other readers might in the future.)
|
| - Elena wasn't thrilled about that, and I don't blame her, but we
|
| - couldn't come up with a better way to get that information. If
|
| - it's needed in other situations, we could consider breaking up
|
| - SYMBOL_SET_NAMES to provide access to the demangled name lookup
|
| - cache. */
|
| -
|
| -const struct partial_symbol *
|
| +void
|
| add_psymbol_to_list (const char *name, int namelength, int copy_name,
|
| domain_enum domain,
|
| enum address_class class,
|
| @@ -1600,11 +1690,10 @@ add_psymbol_to_list (const char *name, int namelength, int copy_name,
|
| /* Do not duplicate global partial symbols. */
|
| if (list == &objfile->global_psymbols
|
| && !added)
|
| - return psym;
|
| + return;
|
|
|
| /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
|
| append_psymbol_to_list (list, psym, objfile);
|
| - return psym;
|
| }
|
|
|
| /* Initialize storage for partial symbols. */
|
| @@ -1674,6 +1763,26 @@ allocate_psymtab (const char *filename, struct objfile *objfile)
|
| psymtab->next = objfile->psymtabs;
|
| objfile->psymtabs = psymtab;
|
|
|
| + if (symtab_create_debug)
|
| + {
|
| + /* Be a bit clever with debugging messages, and don't print objfile
|
| + every time, only when it changes. */
|
| + static char *last_objfile_name = NULL;
|
| +
|
| + if (last_objfile_name == NULL
|
| + || strcmp (last_objfile_name, objfile->name) != 0)
|
| + {
|
| + xfree (last_objfile_name);
|
| + last_objfile_name = xstrdup (objfile->name);
|
| + fprintf_unfiltered (gdb_stdlog,
|
| + "Creating one or more psymtabs for objfile %s ...\n",
|
| + last_objfile_name);
|
| + }
|
| + fprintf_unfiltered (gdb_stdlog,
|
| + "Created psymtab %s for module %s.\n",
|
| + host_address_to_string (psymtab), filename);
|
| + }
|
| +
|
| return (psymtab);
|
| }
|
|
|
| @@ -1874,7 +1983,7 @@ maintenance_check_symtabs (char *ignore, int from_tty)
|
| {
|
| struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
|
|
| - s = PSYMTAB_TO_SYMTAB (ps);
|
| + s = psymtab_to_symtab (ps);
|
| if (s == NULL)
|
| continue;
|
| bv = BLOCKVECTOR (s);
|
| @@ -1945,8 +2054,7 @@ maintenance_check_symtabs (char *ignore, int from_tty)
|
|
|
|
|
| void
|
| -expand_partial_symbol_names (int (*fun) (const struct language_defn *,
|
| - const char *, void *),
|
| +expand_partial_symbol_names (int (*fun) (const char *, void *),
|
| void *data)
|
| {
|
| struct objfile *objfile;
|
|
|