X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpsymtab.c;h=203bfcc6fb4035c9d63a18a3127099b2827045d2;hb=ae6a105d22fb603dbfb956bbcedf9ae469323d55;hp=5fb8ad4887ec4e2aa386f3e1172441868f3fa812;hpb=a2ca7a527ea93943b440b592de2f71c5a9e03392;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 5fb8ad4887..203bfcc6fb 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1,6 +1,6 @@ /* Partial symbol tables. - Copyright (C) 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2009-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,6 @@ #include "symtab.h" #include "psympriv.h" #include "objfiles.h" -#include "gdb_assert.h" #include "block.h" #include "filenames.h" #include "source.h" @@ -35,6 +34,7 @@ #include "dictionary.h" #include "language.h" #include "cp-support.h" +#include "gdbcmd.h" #ifndef DEV_TTY #define DEV_TTY "/dev/tty" @@ -45,27 +45,30 @@ struct psymbol_bcache struct bcache *bcache; }; -static struct partial_symbol *match_partial_symbol (struct partial_symtab *, +static struct partial_symbol *match_partial_symbol (struct objfile *, + struct partial_symtab *, int, const char *, domain_enum, symbol_compare_ftype *, symbol_compare_ftype *); -static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, +static struct partial_symbol *lookup_partial_symbol (struct objfile *, + struct partial_symtab *, const char *, int, domain_enum); -static char *psymtab_to_fullname (struct partial_symtab *ps); +static const char *psymtab_to_fullname (struct partial_symtab *ps); -static struct partial_symbol *find_pc_sect_psymbol (struct partial_symtab *, +static struct partial_symbol *find_pc_sect_psymbol (struct objfile *, + struct partial_symtab *, CORE_ADDR, struct obj_section *); -static struct partial_symbol *fixup_psymbol_section (struct partial_symbol - *psym, - struct objfile *objfile); +static void fixup_psymbol_section (struct partial_symbol *psym, + struct objfile *objfile); -static struct symtab *psymtab_to_symtab (struct partial_symtab *pst); +static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile, + struct partial_symtab *pst); /* Ensure that the partial symbols for OBJFILE have been loaded. This function always returns its argument, as a convenience. */ @@ -82,7 +85,7 @@ require_partial_symbols (struct objfile *objfile, int verbose) if (verbose) { printf_unfiltered (_("Reading symbols from %s..."), - objfile->name); + objfile_name (objfile)); gdb_flush (gdb_stdout); } (*objfile->sf->sym_read_psymbols) (objfile); @@ -121,19 +124,22 @@ require_partial_symbols (struct objfile *objfile, int verbose) ALL_OBJFILES (objfile) \ ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p) -/* Helper function for partial_map_symtabs_matching_filename that +/* Helper function for psym_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; + struct compunit_symtab *last_made = objfile->compunit_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) @@ -141,37 +147,43 @@ partial_map_expand_apply (struct objfile *objfile, /* This may expand more than one symtab, and we want to iterate over all of them. */ - psymtab_to_symtab (pst); + psymtab_to_symtab (objfile, pst); - return iterate_over_some_symtabs (name, full_path, real_path, callback, data, - objfile->symtabs, last_made); + return iterate_over_some_symtabs (name, real_path, callback, data, + objfile->compunit_symtabs, last_made); } -/* Implementation of the map_symtabs_matching_filename method. */ +/* Psymtab version of map_symtabs_matching_filename. See its definition in + the definition of quick_symbol_functions in symfile.h. */ 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) +psym_map_symtabs_matching_filename (struct objfile *objfile, + const char *name, + 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_REQUIRED (objfile, pst) { - if (FILENAME_CMP (name, pst->filename) == 0 - || (!is_abs && compare_filenames_for_search (pst->filename, - name, name_len))) + /* 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 (compare_filenames_for_search (pst->filename, name)) { - if (partial_map_expand_apply (objfile, name, full_path, real_path, + if (partial_map_expand_apply (objfile, name, real_path, pst, callback, data)) return 1; + continue; } /* Before we invoke realpath, which can get expensive when many @@ -180,39 +192,26 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, && 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) + if (compare_filenames_for_search (psymtab_to_fullname (pst), name)) { - psymtab_to_fullname (pst); - if (pst->fullname != NULL - && (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)) - return 1; - } + if (partial_map_expand_apply (objfile, name, real_path, + pst, callback, data)) + return 1; + continue; } + /* If the user gave us an absolute path, try to find the file in + this symtab and use its absolute path. */ if (real_path != NULL) { - char *rp = NULL; - psymtab_to_fullname (pst); - if (pst->fullname != NULL) - { - rp = gdb_realpath (pst->fullname); - make_cleanup (xfree, rp); - } - if (rp != NULL - && (FILENAME_CMP (real_path, rp) == 0 - || (!is_abs && compare_filenames_for_search (real_path, - name, name_len)))) + gdb_assert (IS_ABSOLUTE_PATH (real_path)); + gdb_assert (IS_ABSOLUTE_PATH (name)); + if (filename_cmp (psymtab_to_fullname (pst), real_path) == 0) { - if (partial_map_expand_apply (objfile, name, full_path, real_path, + if (partial_map_expand_apply (objfile, name, real_path, pst, callback, data)) return 1; + continue; } } } @@ -224,11 +223,11 @@ partial_map_symtabs_matching_filename (struct objfile *objfile, We may find a different psymtab than PST. See FIND_PC_SECT_PSYMTAB. */ static struct partial_symtab * -find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, +find_pc_sect_psymtab_closer (struct objfile *objfile, + CORE_ADDR pc, struct obj_section *section, struct partial_symtab *pst, - struct minimal_symbol *msymbol) + struct bound_minimal_symbol msymbol) { - struct objfile *objfile = pst->objfile; struct partial_symtab *tpst; struct partial_symtab *best_pst = pst; CORE_ADDR best_addr = pst->textlow; @@ -243,7 +242,7 @@ find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, section == 0) /* Can't validate section this way. */ return pst; - if (msymbol == NULL) + if (msymbol.minsym == NULL) return (pst); /* The code range of partial symtabs sometimes overlap, so, in @@ -264,10 +263,10 @@ find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, corresponding msymbol, which is not necessarily true; the debug info might be much richer than the object's symbol table. */ - p = find_pc_sect_psymbol (tpst, pc, section); + p = find_pc_sect_psymbol (objfile, tpst, pc, section); if (p != NULL && SYMBOL_VALUE_ADDRESS (p) - == SYMBOL_VALUE_ADDRESS (msymbol)) + == BMSYMBOL_VALUE_ADDRESS (msymbol)) return tpst; /* Also accept the textlow value of a psymtab as a @@ -306,7 +305,7 @@ find_pc_sect_psymtab_closer (CORE_ADDR pc, struct obj_section *section, static struct partial_symtab * find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, struct obj_section *section, - struct minimal_symbol *msymbol) + struct bound_minimal_symbol msymbol) { struct partial_symtab *pst; @@ -321,7 +320,7 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, /* FIXME: addrmaps currently do not handle overlayed sections, so fall back to the non-addrmap case if we're debugging overlays and the addrmap returned the wrong section. */ - if (overlay_debugging && msymbol && section) + if (overlay_debugging && msymbol.minsym && section) { struct partial_symbol *p; @@ -329,10 +328,10 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, corresponding msymbol, which is not necessarily true; the debug info might be much richer than the object's symbol table. */ - p = find_pc_sect_psymbol (pst, pc, section); + p = find_pc_sect_psymbol (objfile, pst, pc, section); if (!p || SYMBOL_VALUE_ADDRESS (p) - != SYMBOL_VALUE_ADDRESS (msymbol)) + != BMSYMBOL_VALUE_ADDRESS (msymbol)) goto next; } @@ -363,7 +362,8 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, { struct partial_symtab *best_pst; - best_pst = find_pc_sect_psymtab_closer (pc, section, pst, msymbol); + best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst, + msymbol); if (best_pst != NULL) return best_pst; } @@ -371,11 +371,15 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, return NULL; } -static struct symtab * -find_pc_sect_symtab_from_partial (struct objfile *objfile, - struct minimal_symbol *msymbol, - CORE_ADDR pc, struct obj_section *section, - int warn_if_readin) +/* Psymtab version of find_pc_sect_compunit_symtab. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + +static struct compunit_symtab * +psym_find_pc_sect_compunit_symtab (struct objfile *objfile, + struct bound_minimal_symbol msymbol, + CORE_ADDR pc, + struct obj_section *section, + int warn_if_readin) { struct partial_symtab *ps = find_pc_sect_psymtab (objfile, pc, section, msymbol); @@ -387,8 +391,9 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile, continue, so let's not. */ 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); + paddress (get_objfile_arch (objfile), pc)); + psymtab_to_symtab (objfile, ps); + return ps->compunit_symtab; } return NULL; } @@ -397,7 +402,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile, Return 0 if none. */ static struct partial_symbol * -find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, +find_pc_sect_psymbol (struct objfile *objfile, + struct partial_symtab *psymtab, CORE_ADDR pc, struct obj_section *section) { struct partial_symbol *best = NULL, *p, **pp; @@ -411,14 +417,14 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, /* Search the global symbols as well as the static symbols, so that find_pc_partial_function doesn't use a minimal symbol and thus cache a bad endaddr. */ - for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset; - (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset) + for (pp = objfile->global_psymbols.list + psymtab->globals_offset; + (pp - (objfile->global_psymbols.list + psymtab->globals_offset) < psymtab->n_global_syms); pp++) { p = *pp; if (SYMBOL_DOMAIN (p) == VAR_DOMAIN - && SYMBOL_CLASS (p) == LOC_BLOCK + && PSYMBOL_CLASS (p) == LOC_BLOCK && pc >= SYMBOL_VALUE_ADDRESS (p) && (SYMBOL_VALUE_ADDRESS (p) > best_pc || (psymtab->textlow == 0 @@ -426,8 +432,9 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, { if (section) /* Match on a specific section. */ { - fixup_psymbol_section (p, psymtab->objfile); - if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section)) + fixup_psymbol_section (p, objfile); + if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p), + section)) continue; } best_pc = SYMBOL_VALUE_ADDRESS (p); @@ -435,14 +442,14 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, } } - for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset; - (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset) + for (pp = objfile->static_psymbols.list + psymtab->statics_offset; + (pp - (objfile->static_psymbols.list + psymtab->statics_offset) < psymtab->n_static_syms); pp++) { p = *pp; if (SYMBOL_DOMAIN (p) == VAR_DOMAIN - && SYMBOL_CLASS (p) == LOC_BLOCK + && PSYMBOL_CLASS (p) == LOC_BLOCK && pc >= SYMBOL_VALUE_ADDRESS (p) && (SYMBOL_VALUE_ADDRESS (p) > best_pc || (psymtab->textlow == 0 @@ -450,8 +457,9 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, { if (section) /* Match on a specific section. */ { - fixup_psymbol_section (p, psymtab->objfile); - if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section)) + fixup_psymbol_section (p, objfile); + if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p), + section)) continue; } best_pc = SYMBOL_VALUE_ADDRESS (p); @@ -462,20 +470,20 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc, return best; } -static struct partial_symbol * +static void fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) { CORE_ADDR addr; if (!psym) - return NULL; + return; - if (SYMBOL_OBJ_SECTION (psym)) - return psym; + if (SYMBOL_SECTION (psym) >= 0) + return; gdb_assert (objfile); - switch (SYMBOL_CLASS (psym)) + switch (PSYMBOL_CLASS (psym)) { case LOC_STATIC: case LOC_LABEL: @@ -485,48 +493,55 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile) default: /* Nothing else will be listed in the minsyms -- no use looking it up. */ - return psym; + return; } fixup_section (&psym->ginfo, addr, objfile); - - return psym; } -static struct symtab * -lookup_symbol_aux_psymtabs (struct objfile *objfile, - int block_index, const char *name, - const domain_enum domain) +/* Psymtab version of lookup_symbol. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + +static struct compunit_symtab * +psym_lookup_symbol (struct objfile *objfile, + int block_index, const char *name, + const domain_enum domain) { struct partial_symtab *ps; const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0); + struct compunit_symtab *stab_best = NULL; ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps) { - if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain)) + if (!ps->readin && lookup_partial_symbol (objfile, ps, name, + psymtab_index, domain)) { struct symbol *sym = NULL; - struct symtab *stab = psymtab_to_symtab (ps); + struct compunit_symtab *stab = psymtab_to_symtab (objfile, ps); + /* Note: While psymtab_to_symtab can return NULL if the partial symtab + is empty, we can assume it won't here because lookup_partial_symbol + succeeded. */ + const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab); + struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); /* 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) + sym = block_lookup_symbol (block, name, domain); + + if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) { - struct blockvector *bv = BLOCKVECTOR (stab); - struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); + if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + return stab; - sym = lookup_block_symbol (block, name, domain); + stab_best = stab; } - if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) - return stab; - /* Keep looking through other psymtabs. */ } } - return NULL; + return stab_best; } /* Look in PST for a symbol in DOMAIN whose name matches NAME. Search @@ -538,7 +553,8 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile, with MATCH. Returns the symbol, if found, and otherwise NULL. */ static struct partial_symbol * -match_partial_symbol (struct partial_symtab *pst, int global, +match_partial_symbol (struct objfile *objfile, + struct partial_symtab *pst, int global, const char *name, domain_enum domain, symbol_compare_ftype *match, symbol_compare_ftype *ordered_compare) @@ -551,8 +567,8 @@ match_partial_symbol (struct partial_symtab *pst, int global, if (length == 0) return NULL; start = (global ? - pst->objfile->global_psymbols.list + pst->globals_offset : - pst->objfile->static_psymbols.list + pst->statics_offset); + objfile->global_psymbols.list + pst->globals_offset : + objfile->static_psymbols.list + pst->statics_offset); if (global && ordered_compare) /* Can use a binary search. */ { @@ -608,15 +624,6 @@ match_partial_symbol (struct partial_symtab *pst, int global, return NULL; } -static void -pre_expand_symtabs_matching_psymtabs (struct objfile *objfile, - 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, @@ -633,13 +640,13 @@ psymtab_search_name (const char *name) case language_cplus: case language_java: { - if (strchr (name, '(')) - { - char *ret = cp_remove_params (name); + if (strchr (name, '(')) + { + char *ret = cp_remove_params (name); - if (ret) - return ret; - } + if (ret) + return ret; + } } break; @@ -654,7 +661,8 @@ psymtab_search_name (const char *name) 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, +lookup_partial_symbol (struct objfile *objfile, + struct partial_symtab *pst, const char *name, int global, domain_enum domain) { struct partial_symbol **start, **psym; @@ -672,8 +680,8 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, 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); + objfile->global_psymbols.list + pst->globals_offset : + objfile->static_psymbols.list + pst->statics_offset); if (global) /* This means we can use a binary search. */ { @@ -755,31 +763,42 @@ 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. */ + This is fast after the first time you do it. + The result will be NULL if the primary symtab has no symbols, + which can happen. Otherwise the result is the primary symtab + that contains PST. */ -static struct symtab * -psymtab_to_symtab (struct partial_symtab *pst) +static struct compunit_symtab * +psymtab_to_symtab (struct objfile *objfile, 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; + if (pst->compunit_symtab) + return pst->compunit_symtab; /* If it has not yet been read in, read it. */ if (!pst->readin) { struct cleanup *back_to = increment_reading_symtab (); - (*pst->read_symtab) (pst); + (*pst->read_symtab) (pst, objfile); do_cleanups (back_to); } - return pst->symtab; + return pst->compunit_symtab; } +/* Psymtab version of relocate. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -relocate_psymtabs (struct objfile *objfile, - struct section_offsets *new_offsets, - struct section_offsets *delta) +psym_relocate (struct objfile *objfile, + const struct section_offsets *new_offsets, + const struct section_offsets *delta) { struct partial_symbol **psym; struct partial_symtab *p; @@ -810,8 +829,11 @@ relocate_psymtabs (struct objfile *objfile, } } +/* Psymtab version of find_last_source_symtab. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static struct symtab * -find_last_source_symtab_from_partial (struct objfile *ofp) +psym_find_last_source_symtab (struct objfile *ofp) { struct partial_symtab *ps; struct partial_symtab *cs_pst = 0; @@ -835,13 +857,22 @@ find_last_source_symtab_from_partial (struct objfile *ofp) "readin pst found and no symtabs.")); } else - return psymtab_to_symtab (cs_pst); + { + struct compunit_symtab *cust = psymtab_to_symtab (ofp, cs_pst); + + if (cust == NULL) + return NULL; + return compunit_primary_filetab (cust); + } } return NULL; } +/* Psymtab version of forget_cached_source_info. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -forget_cached_source_info_partial (struct objfile *objfile) +psym_forget_cached_source_info (struct objfile *objfile) { struct partial_symtab *pst; @@ -863,6 +894,7 @@ print_partial_symbols (struct gdbarch *gdbarch, fprintf_filtered (outfile, " %s partial symbols:\n", what); while (count-- > 0) { + QUIT; fprintf_filtered (outfile, " `%s'", SYMBOL_LINKAGE_NAME (*p)); if (SYMBOL_DEMANGLED_NAME (*p) != NULL) { @@ -887,7 +919,7 @@ print_partial_symbols (struct gdbarch *gdbarch, fputs_filtered (", ", outfile); break; } - switch (SYMBOL_CLASS (*p)) + switch (PSYMBOL_CLASS (*p)) { case LOC_UNDEF: fputs_filtered ("undefined", outfile); @@ -952,13 +984,21 @@ 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"); fprintf_unfiltered (outfile, " Read from object file %s (", - objfile->name); + objfile_name (objfile)); gdb_print_host_address (objfile, outfile); fprintf_unfiltered (outfile, ")\n"); @@ -966,14 +1006,14 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, { fprintf_filtered (outfile, " Full symtab was read (at "); - gdb_print_host_address (psymtab->symtab, outfile); + gdb_print_host_address (psymtab->compunit_symtab, outfile); fprintf_filtered (outfile, " by function at "); gdb_print_host_address (psymtab->read_symtab, outfile); fprintf_filtered (outfile, ")\n"); } fprintf_filtered (outfile, " Relocate symbols by "); - for (i = 0; i < psymtab->objfile->num_sections; ++i) + for (i = 0; i < objfile->num_sections; ++i) { if (i != 0) fprintf_filtered (outfile, ", "); @@ -1000,6 +1040,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, @@ -1017,8 +1063,11 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab, fprintf_filtered (outfile, "\n"); } +/* Psymtab version of print_stats. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -print_psymtab_stats_for_objfile (struct objfile *objfile) +psym_print_stats (struct objfile *objfile) { int i; struct partial_symtab *ps; @@ -1032,8 +1081,11 @@ print_psymtab_stats_for_objfile (struct objfile *objfile) printf_filtered (_(" Number of psym tables (not yet expanded): %d\n"), i); } +/* Psymtab version of dump. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -dump_psymtabs_for_objfile (struct objfile *objfile) +psym_dump (struct objfile *objfile) { struct partial_symtab *psymtab; @@ -1048,21 +1100,18 @@ dump_psymtabs_for_objfile (struct objfile *objfile) psymtab->filename); gdb_print_host_address (psymtab, gdb_stdout); printf_filtered (", "); - if (psymtab->objfile != objfile) - { - printf_filtered ("NOT ON CHAIN! "); - } wrap_here (" "); } printf_filtered ("\n\n"); } } -/* Look through the partial symtabs for all symbols which begin - by matching FUNC_NAME. Make sure we read that symbol table in. */ +/* Psymtab version of expand_symtabs_for_function. See its definition in + the definition of quick_symbol_functions in symfile.h. */ static void -read_symtabs_for_function (struct objfile *objfile, const char *func_name) +psym_expand_symtabs_for_function (struct objfile *objfile, + const char *func_name) { struct partial_symtab *ps; @@ -1071,41 +1120,59 @@ read_symtabs_for_function (struct objfile *objfile, const char *func_name) if (ps->readin) continue; - if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN) + if ((lookup_partial_symbol (objfile, ps, func_name, 1, VAR_DOMAIN) != NULL) - || (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN) + || (lookup_partial_symbol (objfile, ps, func_name, 0, VAR_DOMAIN) != NULL)) - psymtab_to_symtab (ps); + psymtab_to_symtab (objfile, ps); } } +/* Psymtab version of expand_all_symtabs. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -expand_partial_symbol_tables (struct objfile *objfile) +psym_expand_all_symtabs (struct objfile *objfile) { struct partial_symtab *psymtab; ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab) { - psymtab_to_symtab (psymtab); + psymtab_to_symtab (objfile, psymtab); } } +/* Psymtab version of expand_symtabs_with_fullname. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -read_psymtabs_with_filename (struct objfile *objfile, const char *filename) +psym_expand_symtabs_with_fullname (struct objfile *objfile, + const char *fullname) { struct partial_symtab *p; ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p) { - if (filename_cmp (filename, p->filename) == 0) - psymtab_to_symtab (p); + /* Anonymous psymtabs don't have a name of a source file. */ + if (p->anonymous) + continue; + + /* psymtab_to_fullname tries to open the file which is slow. + Don't call it if we know the basenames don't match. */ + if ((basenames_may_differ + || filename_cmp (lbasename (fullname), lbasename (p->filename)) == 0) + && filename_cmp (fullname, psymtab_to_fullname (p)) == 0) + psymtab_to_symtab (objfile, p); } } +/* Psymtab version of map_symbol_filenames. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -map_symbol_filenames_psymtab (struct objfile *objfile, - symbol_filename_ftype *fun, void *data, - int need_fullname) +psym_map_symbol_filenames (struct objfile *objfile, + symbol_filename_ftype *fun, void *data, + int need_fullname) { struct partial_symtab *ps; @@ -1116,6 +1183,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,42 +1209,42 @@ map_symbol_filenames_psymtab (struct objfile *objfile, 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 * +static const char * psymtab_to_fullname (struct partial_symtab *ps) { - int r; - - if (!ps) - return NULL; + gdb_assert (!ps->anonymous); /* 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; + if (ps->fullname == NULL) + { + int fd = find_and_open_source (ps->filename, ps->dirname, &ps->fullname); - r = find_and_open_source (ps->filename, ps->dirname, &ps->fullname); + if (fd >= 0) + close (fd); + else + { + char *fullname; + struct cleanup *back_to; - if (r >= 0) - { - close (r); - return ps->fullname; - } + /* rewrite_source_path would be applied by find_and_open_source, we + should report the pathname where GDB tried to find the file. */ - return NULL; -} + if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename)) + fullname = xstrdup (ps->filename); + else + fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL); -static const char * -find_symbol_file_from_partial (struct objfile *objfile, const char *name) -{ - struct partial_symtab *pst; + back_to = make_cleanup (xfree, fullname); + ps->fullname = rewrite_source_path (fullname); + if (ps->fullname == NULL) + ps->fullname = xstrdup (fullname); + do_cleanups (back_to); + } + } - ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst) - { - if (lookup_partial_symbol (pst, name, 1, VAR_DOMAIN)) - return pst->filename; - } - return NULL; + return ps->fullname; } /* For all symbols, s, in BLOCK that are in NAMESPACE and match NAME @@ -1182,11 +1258,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)) @@ -1203,13 +1279,14 @@ map_block (const char *name, domain_enum namespace, struct objfile *objfile, the definition of quick_symbol_functions in symfile.h. */ static void -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) +psym_map_matching_symbols (struct objfile *objfile, + const char *name, domain_enum namespace, + 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; @@ -1218,15 +1295,15 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace, { QUIT; if (ps->readin - || match_partial_symbol (ps, global, name, namespace, match, + || match_partial_symbol (objfile, ps, global, name, namespace, match, ordered_compare)) { - struct symtab *s = psymtab_to_symtab (ps); + struct compunit_symtab *cust = psymtab_to_symtab (objfile, ps); struct block *block; - if (s == NULL || !s->primary) + if (cust == NULL) continue; - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind); + block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind); if (map_block (name, namespace, objfile, block, callback, data, match)) return; @@ -1236,98 +1313,174 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace, } } +/* A helper for psym_expand_symtabs_matching 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, + expand_symtabs_symbol_matcher_ftype *sym_matcher, + 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, sym_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 + && PSYMBOL_CLASS (*psym) != LOC_TYPEDEF + && PSYMBOL_CLASS (*psym) != LOC_BLOCK) + || (kind == FUNCTIONS_DOMAIN + && PSYMBOL_CLASS (*psym) == LOC_BLOCK) + || (kind == TYPES_DOMAIN + && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF)) + && (*sym_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; +} + +/* Psymtab version of expand_symtabs_matching. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static void -expand_symtabs_matching_via_partial +psym_expand_symtabs_matching (struct objfile *objfile, - int (*file_matcher) (const char *, void *), - int (*name_matcher) (const char *, void *), + expand_symtabs_file_matcher_ftype *file_matcher, + expand_symtabs_symbol_matcher_ftype *symbol_matcher, 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 + int match; + + if (ps->anonymous) + continue; + + match = (*file_matcher) (ps->filename, data, 0); + if (!match) { - 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)) - { - psymtab_to_symtab (ps); - keep_going = 0; - } + /* Before we invoke realpath, which can get expensive when many + files are involved, do a quick comparison of the basenames. */ + if (basenames_may_differ + || (*file_matcher) (lbasename (ps->filename), data, 1)) + match = (*file_matcher) (psymtab_to_fullname (ps), data, 0); } - psym++; + if (!match) + continue; } + + if (recursively_search_psymtabs (ps, objfile, kind, symbol_matcher, data)) + psymtab_to_symtab (objfile, ps); } } +/* Psymtab version of has_symbols. See its definition in + the definition of quick_symbol_functions in symfile.h. */ + static int -objfile_has_psyms (struct objfile *objfile) +psym_has_symbols (struct objfile *objfile) { return objfile->psymtabs != NULL; } const struct quick_symbol_functions psym_functions = { - objfile_has_psyms, - find_last_source_symtab_from_partial, - forget_cached_source_info_partial, - partial_map_symtabs_matching_filename, - lookup_symbol_aux_psymtabs, - pre_expand_symtabs_matching_psymtabs, - print_psymtab_stats_for_objfile, - dump_psymtabs_for_objfile, - relocate_psymtabs, - read_symtabs_for_function, - expand_partial_symbol_tables, - read_psymtabs_with_filename, - find_symbol_file_from_partial, - map_matching_symbols_psymtab, - expand_symtabs_matching_via_partial, - find_pc_sect_symtab_from_partial, - map_symbol_filenames_psymtab + psym_has_symbols, + psym_find_last_source_symtab, + psym_forget_cached_source_info, + psym_map_symtabs_matching_filename, + psym_lookup_symbol, + psym_print_stats, + psym_dump, + psym_relocate, + psym_expand_symtabs_for_function, + psym_expand_all_symtabs, + psym_expand_symtabs_with_fullname, + psym_map_matching_symbols, + psym_expand_symtabs_matching, + psym_find_pc_sect_compunit_symtab, + psym_map_symbol_filenames }; @@ -1346,11 +1499,11 @@ compare_psymbols (const void *s1p, const void *s2p) } void -sort_pst_symbols (struct partial_symtab *pst) +sort_pst_symbols (struct objfile *objfile, struct partial_symtab *pst) { /* Sort the global list; don't sort the static list. */ - qsort (pst->objfile->global_psymbols.list + pst->globals_offset, + qsort (objfile->global_psymbols.list + pst->globals_offset, pst->n_global_syms, sizeof (struct partial_symbol *), compare_psymbols); } @@ -1424,7 +1577,7 @@ psymbol_compare (const void *addr1, const void *addr2, int length) struct psymbol_bcache * psymbol_bcache_init (void) { - struct psymbol_bcache *bcache = XCALLOC (1, struct psymbol_bcache); + struct psymbol_bcache *bcache = XCNEW (struct psymbol_bcache); bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare); return bcache; } @@ -1481,10 +1634,10 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name, { struct partial_symbol psymbol; - /* We must ensure that the entire 'value' field has been zeroed - before assigning to it, because an assignment may not write the - entire field. */ - memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value)); + /* We must ensure that the entire struct has been zeroed before + assigning to it, because an assignment may not touch some of the + holes. */ + memset (&psymbol, 0, sizeof (psymbol)); /* val and coreaddr are mutually exclusive, one of them *will* be zero. */ if (val != 0) @@ -1495,9 +1648,8 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name, { SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr; } - SYMBOL_SECTION (&psymbol) = 0; - SYMBOL_OBJ_SECTION (&psymbol) = NULL; - SYMBOL_SET_LANGUAGE (&psymbol, language); + SYMBOL_SECTION (&psymbol) = -1; + SYMBOL_SET_LANGUAGE (&psymbol, language, &objfile->objfile_obstack); PSYMBOL_DOMAIN (&psymbol) = domain; PSYMBOL_CLASS (&psymbol) = class; @@ -1600,7 +1752,7 @@ init_psymbol_list (struct objfile *objfile, int total_symbols) /* Current best guess is that approximately a twentieth of the total symbols (in a debugging file) are global or static - oriented symbols. */ + oriented symbols, then multiply that by slop factor of two. */ objfile->global_psymbols.size = total_symbols / 10; objfile->static_psymbols.size = total_symbols / 10; @@ -1637,23 +1789,42 @@ allocate_psymtab (const char *filename, struct objfile *objfile) sizeof (struct partial_symtab)); memset (psymtab, 0, sizeof (struct partial_symtab)); - psymtab->filename = obsavestring (filename, strlen (filename), - &objfile->objfile_obstack); - psymtab->symtab = NULL; + psymtab->filename = bcache (filename, strlen (filename) + 1, + objfile->per_bfd->filename_cache); + psymtab->compunit_symtab = NULL; /* Prepend it to the psymtab list for the objfile it belongs to. Psymtabs are searched in most recent inserted -> least recent inserted order. */ - psymtab->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 (objfile)) != 0) + { + xfree (last_objfile_name); + last_objfile_name = xstrdup (objfile_name (objfile)); + 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); } void -discard_psymtab (struct partial_symtab *pst) +discard_psymtab (struct objfile *objfile, struct partial_symtab *pst) { struct partial_symtab **prev_pst; @@ -1666,20 +1837,58 @@ discard_psymtab (struct partial_symtab *pst) /* First, snip it out of the psymtab chain. */ - prev_pst = &(pst->objfile->psymtabs); + prev_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. */ - pst->next = pst->objfile->free_psymtabs; - pst->objfile->free_psymtabs = pst; + pst->next = objfile->free_psymtabs; + objfile->free_psymtabs = pst; +} + +/* An object of this type is passed to discard_psymtabs_upto. */ + +struct psymtab_state +{ + /* The objfile where psymtabs are discarded. */ + + struct objfile *objfile; + + /* The first psymtab to save. */ + + struct partial_symtab *save; +}; + +/* A cleanup function used by make_cleanup_discard_psymtabs. */ + +static void +discard_psymtabs_upto (void *arg) +{ + struct psymtab_state *state = arg; + + while (state->objfile->psymtabs != state->save) + discard_psymtab (state->objfile, state->objfile->psymtabs); +} + +/* Return a new cleanup that discards all psymtabs created in OBJFILE + after this function is called. */ + +struct cleanup * +make_cleanup_discard_psymtabs (struct objfile *objfile) +{ + struct psymtab_state *state = XNEW (struct psymtab_state); + + state->objfile = objfile; + state->save = objfile->psymtabs; + + return make_cleanup_dtor (discard_psymtabs_upto, state, xfree); } -void +static void maintenance_print_psymbols (char *args, int from_tty) { char **argv; @@ -1718,16 +1927,17 @@ print-psymbols takes an output file name and optional symbol file name")); perror_with_name (filename); make_cleanup_ui_file_delete (outfile); - immediate_quit++; ALL_PSYMTABS (objfile, ps) - if (symname == NULL || filename_cmp (symname, ps->filename) == 0) - dump_psymtab (objfile, ps, outfile); - immediate_quit--; + { + QUIT; + if (symname == NULL || filename_cmp (symname, ps->filename) == 0) + dump_psymtab (objfile, ps, outfile); + } do_cleanups (cleanups); } /* List all the partial symbol tables whose names match REGEXP (optional). */ -void +static void maintenance_info_psymtabs (char *regexp, int from_tty) { struct program_space *pspace; @@ -1755,7 +1965,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) { if (! printed_objfile_start) { - printf_filtered ("{ objfile %s ", objfile->name); + printf_filtered ("{ objfile %s ", objfile_name (objfile)); wrap_here (" "); printf_filtered ("((struct objfile *) %s)\n", host_address_to_string (objfile)); @@ -1786,7 +1996,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) if (psymtab->n_global_syms) { printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n", - host_address_to_string (psymtab->objfile->global_psymbols.list + host_address_to_string (objfile->global_psymbols.list + psymtab->globals_offset), psymtab->n_global_syms); } @@ -1796,7 +2006,7 @@ maintenance_info_psymtabs (char *regexp, int from_tty) if (psymtab->n_static_syms) { printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n", - host_address_to_string (psymtab->objfile->static_psymbols.list + host_address_to_string (objfile->static_psymbols.list + psymtab->statics_offset), psymtab->n_static_syms); } @@ -1831,16 +2041,16 @@ maintenance_info_psymtabs (char *regexp, int from_tty) } } -/* Check consistency of psymtabs and symtabs. */ +/* Check consistency of currently expanded psymtabs vs symtabs. */ -void -maintenance_check_symtabs (char *ignore, int from_tty) +static void +maintenance_check_psymtabs (char *ignore, int from_tty) { struct symbol *sym; struct partial_symbol **psym; - struct symtab *s = NULL; + struct compunit_symtab *cust = NULL; struct partial_symtab *ps; - struct blockvector *bv; + const struct blockvector *bv; struct objfile *objfile; struct block *b; int length; @@ -1849,16 +2059,34 @@ maintenance_check_symtabs (char *ignore, int from_tty) { struct gdbarch *gdbarch = get_objfile_arch (objfile); - s = psymtab_to_symtab (ps); - if (s == NULL) + /* We don't call psymtab_to_symtab here because that may cause symtab + expansion. When debugging a problem it helps if checkers leave + things unchanged. */ + cust = ps->compunit_symtab; + + /* First do some checks that don't require the associated symtab. */ + if (ps->texthigh < ps->textlow) + { + printf_filtered ("Psymtab "); + puts_filtered (ps->filename); + printf_filtered (" covers bad range "); + fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); + printf_filtered (" - "); + fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); + printf_filtered ("\n"); + continue; + } + + /* Now do checks requiring the associated symtab. */ + if (cust == NULL) continue; - bv = BLOCKVECTOR (s); + bv = COMPUNIT_BLOCKVECTOR (cust); b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - psym = ps->objfile->static_psymbols.list + ps->statics_offset; + psym = objfile->static_psymbols.list + ps->statics_offset; length = ps->n_static_syms; while (length--) { - sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym), + sym = block_lookup_symbol (b, SYMBOL_LINKAGE_NAME (*psym), SYMBOL_DOMAIN (*psym)); if (!sym) { @@ -1871,11 +2099,11 @@ maintenance_check_symtabs (char *ignore, int from_tty) psym++; } b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - psym = ps->objfile->global_psymbols.list + ps->globals_offset; + psym = objfile->global_psymbols.list + ps->globals_offset; length = ps->n_global_syms; while (length--) { - sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym), + sym = block_lookup_symbol (b, SYMBOL_LINKAGE_NAME (*psym), SYMBOL_DOMAIN (*psym)); if (!sym) { @@ -1887,20 +2115,8 @@ maintenance_check_symtabs (char *ignore, int from_tty) } psym++; } - if (ps->texthigh < ps->textlow) - { - printf_filtered ("Psymtab "); - puts_filtered (ps->filename); - printf_filtered (" covers bad range "); - fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); - printf_filtered (" - "); - fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); - printf_filtered ("\n"); - continue; - } - if (ps->texthigh == 0) - continue; - if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)) + if (ps->texthigh != 0 + && (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b))) { printf_filtered ("Psymtab "); puts_filtered (ps->filename); @@ -1919,30 +2135,25 @@ maintenance_check_symtabs (char *ignore, int from_tty) -void -expand_partial_symbol_names (int (*fun) (const char *, void *), - void *data) -{ - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->expand_symtabs_matching (objfile, NULL, fun, - ALL_DOMAIN, data); - } -} +extern initialize_file_ftype _initialize_psymtab; void -map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data, - int need_fullname) +_initialize_psymtab (void) { - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->map_symbol_filenames (objfile, fun, data, - need_fullname); - } + add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\ +Print dump of current partial symbol definitions.\n\ +Entries in the partial symbol table are dumped to file OUTFILE.\n\ +If a SOURCE file is specified, dump only that file's partial symbols."), + &maintenanceprintlist); + + add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\ +List the partial symbol tables for all object files.\n\ +This does not include information about individual partial symbols,\n\ +just the symbol table structures themselves."), + &maintenanceinfolist); + + add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs, + _("\ +Check consistency of currently expanded psymtabs versus symtabs."), + &maintenancelist); }