| Index: gdb/psymtab.c
|
| diff --git a/gdb/psymtab.c b/gdb/psymtab.c
|
| index 5623e2dc5f8ba30d6b1aa52cb6c9fa3579855d70..1d336623941d08c361a70e737119c830e19bd7b4 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-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -35,6 +35,7 @@
|
| #include "dictionary.h"
|
| #include "language.h"
|
| #include "cp-support.h"
|
| +#include "gdbcmd.h"
|
|
|
| #ifndef DEV_TTY
|
| #define DEV_TTY "/dev/tty"
|
| @@ -45,27 +46,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 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 +86,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);
|
| @@ -127,7 +131,6 @@ require_partial_symbols (struct objfile *objfile, int verbose)
|
| 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 *),
|
| @@ -145,9 +148,9 @@ 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,
|
| + return iterate_over_some_symtabs (name, real_path, callback, data,
|
| objfile->symtabs, last_made);
|
| }
|
|
|
| @@ -156,7 +159,6 @@ partial_map_expand_apply (struct objfile *objfile,
|
| 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 *),
|
| @@ -164,8 +166,6 @@ 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)
|
| {
|
| @@ -178,13 +178,12 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
|
| if (pst->anonymous)
|
| continue;
|
|
|
| - if (FILENAME_CMP (name, pst->filename) == 0
|
| - || (!is_abs && compare_filenames_for_search (pst->filename,
|
| - name, name_len)))
|
| + 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
|
| @@ -193,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;
|
| }
|
| }
|
| }
|
| @@ -237,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 objfile *objfile = pst->objfile;
|
| struct partial_symtab *tpst;
|
| struct partial_symtab *best_pst = pst;
|
| CORE_ADDR best_addr = pst->textlow;
|
| @@ -277,7 +263,7 @@ 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))
|
| @@ -342,7 +328,7 @@ 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))
|
| @@ -376,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;
|
| }
|
| @@ -400,8 +387,8 @@ 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));
|
| - psymtab_to_symtab (ps);
|
| + paddress (get_objfile_arch (objfile), pc));
|
| + psymtab_to_symtab (objfile, ps);
|
| return ps->symtab;
|
| }
|
| return NULL;
|
| @@ -411,7 +398,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;
|
| @@ -425,14 +413,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
|
| @@ -440,8 +428,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);
|
| @@ -449,14 +438,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
|
| @@ -464,8 +453,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);
|
| @@ -476,20 +466,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:
|
| @@ -499,12 +489,10 @@ 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 *
|
| @@ -518,10 +506,11 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
|
|
|
| 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 symtab *stab = psymtab_to_symtab (objfile, ps);
|
|
|
| /* Some caution must be observed with overloaded functions
|
| and methods, since the psymtab will not contain any overload
|
| @@ -558,7 +547,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)
|
| @@ -571,8 +561,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. */
|
| {
|
| @@ -628,15 +618,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,
|
| @@ -674,7 +655,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;
|
| @@ -692,8 +674,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. */
|
| {
|
| @@ -778,7 +760,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
|
| This is fast after the first time you do it. */
|
|
|
| static struct symtab *
|
| -psymtab_to_symtab (struct partial_symtab *pst)
|
| +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. */
|
| @@ -794,7 +776,7 @@ psymtab_to_symtab (struct partial_symtab *pst)
|
| {
|
| struct cleanup *back_to = increment_reading_symtab ();
|
|
|
| - (*pst->read_symtab) (pst);
|
| + (*pst->read_symtab) (pst, objfile);
|
| do_cleanups (back_to);
|
| }
|
|
|
| @@ -803,8 +785,8 @@ psymtab_to_symtab (struct partial_symtab *pst)
|
|
|
| static void
|
| relocate_psymtabs (struct objfile *objfile,
|
| - struct section_offsets *new_offsets,
|
| - struct section_offsets *delta)
|
| + const struct section_offsets *new_offsets,
|
| + const struct section_offsets *delta)
|
| {
|
| struct partial_symbol **psym;
|
| struct partial_symtab *p;
|
| @@ -860,7 +842,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 (ofp, cs_pst);
|
| }
|
| return NULL;
|
| }
|
| @@ -888,6 +870,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)
|
| {
|
| @@ -912,7 +895,7 @@ print_partial_symbols (struct gdbarch *gdbarch,
|
| fputs_filtered ("<invalid domain>, ", outfile);
|
| break;
|
| }
|
| - switch (SYMBOL_CLASS (*p))
|
| + switch (PSYMBOL_CLASS (*p))
|
| {
|
| case LOC_UNDEF:
|
| fputs_filtered ("undefined", outfile);
|
| @@ -991,7 +974,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
|
| 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");
|
|
|
| @@ -1006,7 +989,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
|
| }
|
|
|
| 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, ", ");
|
| @@ -1087,10 +1070,6 @@ 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");
|
| @@ -1110,11 +1089,11 @@ 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);
|
| }
|
| }
|
|
|
| @@ -1125,12 +1104,12 @@ expand_partial_symbol_tables (struct objfile *objfile)
|
|
|
| ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
|
| {
|
| - psymtab_to_symtab (psymtab);
|
| + psymtab_to_symtab (objfile, psymtab);
|
| }
|
| }
|
|
|
| static void
|
| -read_psymtabs_with_filename (struct objfile *objfile, const char *filename)
|
| +read_psymtabs_with_fullname (struct objfile *objfile, const char *fullname)
|
| {
|
| struct partial_symtab *p;
|
|
|
| @@ -1140,8 +1119,12 @@ read_psymtabs_with_filename (struct objfile *objfile, const char *filename)
|
| if (p->anonymous)
|
| continue;
|
|
|
| - if (filename_cmp (filename, p->filename) == 0)
|
| - psymtab_to_symtab (p);
|
| + /* 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);
|
| }
|
| }
|
|
|
| @@ -1185,44 +1168,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;
|
| - if (ps->anonymous)
|
| - 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
|
| @@ -1257,8 +1238,9 @@ 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,
|
| +map_matching_symbols_psymtab (struct objfile *objfile,
|
| + const char *name, domain_enum namespace,
|
| + int global,
|
| int (*callback) (struct block *,
|
| struct symbol *, void *),
|
| void *data,
|
| @@ -1272,10 +1254,10 @@ 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 symtab *s = psymtab_to_symtab (objfile, ps);
|
| struct block *block;
|
|
|
| if (s == NULL || !s->primary)
|
| @@ -1358,12 +1340,12 @@ recursively_search_psymtabs (struct partial_symtab *ps,
|
|
|
| if ((kind == ALL_DOMAIN
|
| || (kind == VARIABLES_DOMAIN
|
| - && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
|
| - && SYMBOL_CLASS (*psym) != LOC_BLOCK)
|
| + && PSYMBOL_CLASS (*psym) != LOC_TYPEDEF
|
| + && PSYMBOL_CLASS (*psym) != LOC_BLOCK)
|
| || (kind == FUNCTIONS_DOMAIN
|
| - && SYMBOL_CLASS (*psym) == LOC_BLOCK)
|
| + && PSYMBOL_CLASS (*psym) == LOC_BLOCK)
|
| || (kind == TYPES_DOMAIN
|
| - && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
| + && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
| && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
|
| {
|
| /* Found a match, so notify our caller. */
|
| @@ -1381,7 +1363,7 @@ recursively_search_psymtabs (struct partial_symtab *ps,
|
| static void
|
| expand_symtabs_matching_via_partial
|
| (struct objfile *objfile,
|
| - int (*file_matcher) (const char *, void *),
|
| + int (*file_matcher) (const char *, void *, int basenames),
|
| int (*name_matcher) (const char *, void *),
|
| enum search_domain kind,
|
| void *data)
|
| @@ -1406,14 +1388,26 @@ expand_symtabs_matching_via_partial
|
|
|
| if (file_matcher)
|
| {
|
| + int match;
|
| +
|
| if (ps->anonymous)
|
| continue;
|
| - if (! (*file_matcher) (ps->filename, data))
|
| +
|
| + match = (*file_matcher) (ps->filename, data, 0);
|
| + if (!match)
|
| + {
|
| + /* 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);
|
| + }
|
| + if (!match)
|
| continue;
|
| }
|
|
|
| if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
|
| - psymtab_to_symtab (ps);
|
| + psymtab_to_symtab (objfile, ps);
|
| }
|
| }
|
|
|
| @@ -1430,14 +1424,12 @@ const struct quick_symbol_functions psym_functions =
|
| 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,
|
| + read_psymtabs_with_fullname,
|
| map_matching_symbols_psymtab,
|
| expand_symtabs_matching_via_partial,
|
| find_pc_sect_symtab_from_partial,
|
| @@ -1460,11 +1452,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);
|
| }
|
| @@ -1595,10 +1587,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)
|
| @@ -1609,9 +1601,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;
|
|
|
| @@ -1714,7 +1705,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;
|
| @@ -1751,15 +1742,14 @@ 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->filename = bcache (filename, strlen (filename) + 1,
|
| + objfile->per_bfd->filename_cache);
|
| psymtab->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;
|
|
|
| @@ -1770,10 +1760,10 @@ allocate_psymtab (const char *filename, struct objfile *objfile)
|
| static char *last_objfile_name = NULL;
|
|
|
| if (last_objfile_name == NULL
|
| - || strcmp (last_objfile_name, objfile->name) != 0)
|
| + || strcmp (last_objfile_name, objfile_name (objfile)) != 0)
|
| {
|
| xfree (last_objfile_name);
|
| - last_objfile_name = xstrdup (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);
|
| @@ -1787,7 +1777,7 @@ allocate_psymtab (const char *filename, struct objfile *objfile)
|
| }
|
|
|
| void
|
| -discard_psymtab (struct partial_symtab *pst)
|
| +discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
|
| {
|
| struct partial_symtab **prev_pst;
|
|
|
| @@ -1800,20 +1790,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;
|
| @@ -1852,16 +1880,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;
|
| @@ -1889,7 +1918,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));
|
| @@ -1920,7 +1949,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);
|
| }
|
| @@ -1930,7 +1959,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);
|
| }
|
| @@ -1965,10 +1994,10 @@ 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;
|
| @@ -1983,12 +2012,30 @@ maintenance_check_symtabs (char *ignore, int from_tty)
|
| {
|
| struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
|
|
| - s = psymtab_to_symtab (ps);
|
| + /* 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. */
|
| + s = ps->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 (s == NULL)
|
| continue;
|
| bv = BLOCKVECTOR (s);
|
| 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--)
|
| {
|
| @@ -2005,7 +2052,7 @@ 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--)
|
| {
|
| @@ -2021,20 +2068,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);
|
| @@ -2080,3 +2115,26 @@ map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
|
| need_fullname);
|
| }
|
| }
|
| +
|
| +extern initialize_file_ftype _initialize_psymtab;
|
| +
|
| +void
|
| +_initialize_psymtab (void)
|
| +{
|
| + 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);
|
| +}
|
|
|