/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2014 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 Free Software Foundation, Inc.
This file is part of GDB.
const domain_enum domain,
enum language language);
-static
-struct symbol *lookup_symbol_via_quick_fns (struct objfile *objfile,
- int block_index,
- const char *name,
- const domain_enum domain);
+static struct symbol *
+ lookup_symbol_in_objfile (struct objfile *objfile, int block_index,
+ const char *name, const domain_enum domain);
extern initialize_file_ftype _initialize_symtab;
/* When non-zero, print debugging messages related to symtab creation. */
unsigned int symtab_create_debug = 0;
+/* When non-zero, print debugging messages related to symbol lookup. */
+unsigned int symbol_lookup_debug = 0;
+
/* Non-zero if a file may be known by two different basenames.
This is the uncommon case, and significantly slows down gdb.
Default set to "off" to not slow down the common case. */
case UNDEF_DOMAIN: return "UNDEF_DOMAIN";
case VAR_DOMAIN: return "VAR_DOMAIN";
case STRUCT_DOMAIN: return "STRUCT_DOMAIN";
+ case MODULE_DOMAIN: return "MODULE_DOMAIN";
case LABEL_DOMAIN: return "LABEL_DOMAIN";
case COMMON_BLOCK_DOMAIN: return "COMMON_BLOCK_DOMAIN";
default: gdb_assert_not_reached ("bad domain_enum");
}
}
-/* Set the primary field in SYMTAB. */
+/* See symtab.h. */
-void
-set_symtab_primary (struct symtab *symtab, int primary)
+struct symtab *
+compunit_primary_filetab (const struct compunit_symtab *cust)
{
- symtab->primary = primary;
+ gdb_assert (COMPUNIT_FILETABS (cust) != NULL);
- if (symtab_create_debug && primary)
- {
- fprintf_unfiltered (gdb_stdlog,
- "Created primary symtab %s for %s.\n",
- host_address_to_string (symtab),
- symtab_to_filename_for_display (symtab));
- }
+ /* The primary file symtab is the first one in the list. */
+ return COMPUNIT_FILETABS (cust);
+}
+
+/* See symtab.h. */
+
+enum language
+compunit_language (const struct compunit_symtab *cust)
+{
+ struct symtab *symtab = compunit_primary_filetab (cust);
+
+/* The language of the compunit symtab is the language of its primary
+ source file. */
+ return SYMTAB_LANGUAGE (symtab);
}
/* See whether FILENAME matches SEARCH_NAME using the rule that we
are identical to the `map_symtabs_matching_filename' method of
quick_symbol_functions.
- FIRST and AFTER_LAST indicate the range of symtabs to search.
- AFTER_LAST is one past the last symtab to search; NULL means to
+ FIRST and AFTER_LAST indicate the range of compunit symtabs to search.
+ Each symtab within the specified compunit symtab is also searched.
+ AFTER_LAST is one past the last compunit symtab to search; NULL means to
search until the end of the list. */
int
int (*callback) (struct symtab *symtab,
void *data),
void *data,
- struct symtab *first,
- struct symtab *after_last)
+ struct compunit_symtab *first,
+ struct compunit_symtab *after_last)
{
- struct symtab *s = NULL;
+ struct compunit_symtab *cust;
+ struct symtab *s;
const char* base_name = lbasename (name);
- for (s = first; s != NULL && s != after_last; s = s->next)
+ for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
{
- if (compare_filenames_for_search (s->filename, name))
+ ALL_COMPUNIT_FILETABS (cust, s)
{
- if (callback (s, data))
- return 1;
- continue;
- }
-
- /* Before we invoke realpath, which can get expensive when many
- files are involved, do a quick comparison of the basenames. */
- if (! basenames_may_differ
- && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
- continue;
-
- if (compare_filenames_for_search (symtab_to_fullname (s), name))
- {
- if (callback (s, data))
- return 1;
- continue;
- }
+ if (compare_filenames_for_search (s->filename, name))
+ {
+ if (callback (s, 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)
- {
- const char *fullname = symtab_to_fullname (s);
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
+ continue;
- gdb_assert (IS_ABSOLUTE_PATH (real_path));
- gdb_assert (IS_ABSOLUTE_PATH (name));
- if (FILENAME_CMP (real_path, fullname) == 0)
+ if (compare_filenames_for_search (symtab_to_fullname (s), name))
{
if (callback (s, 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)
+ {
+ const char *fullname = symtab_to_fullname (s);
+
+ gdb_assert (IS_ABSOLUTE_PATH (real_path));
+ gdb_assert (IS_ABSOLUTE_PATH (name));
+ if (FILENAME_CMP (real_path, fullname) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ continue;
+ }
+ }
}
}
ALL_OBJFILES (objfile)
{
if (iterate_over_some_symtabs (name, real_path, callback, data,
- objfile->symtabs, NULL))
+ objfile->compunit_symtabs, NULL))
{
do_cleanups (cleanups);
return;
return (mangled_name);
}
-/* Initialize the cplus_specific structure. 'cplus_specific' should
- only be allocated for use with cplus symbols. */
-
-static void
-symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
- struct obstack *obstack)
-{
- /* A language_specific structure should not have been previously
- initialized. */
- gdb_assert (gsymbol->language_specific.cplus_specific == NULL);
- gdb_assert (obstack != NULL);
-
- gsymbol->language_specific.cplus_specific =
- OBSTACK_ZALLOC (obstack, struct cplus_specific);
-}
-
/* Set the demangled name of GSYMBOL to NAME. NAME must be already
- correctly allocated. For C++ symbols a cplus_specific struct is
- allocated so OBJFILE must not be NULL. If this is a non C++ symbol
- OBJFILE can be NULL. */
+ correctly allocated. */
void
symbol_set_demangled_name (struct general_symbol_info *gsymbol,
const char *name,
struct obstack *obstack)
{
- if (gsymbol->language == language_cplus)
- {
- if (gsymbol->language_specific.cplus_specific == NULL)
- symbol_init_cplus_specific (gsymbol, obstack);
-
- gsymbol->language_specific.cplus_specific->demangled_name = name;
- }
- else if (gsymbol->language == language_ada)
+ if (gsymbol->language == language_ada)
{
if (name == NULL)
{
const char *
symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
{
- if (gsymbol->language == language_cplus)
- {
- if (gsymbol->language_specific.cplus_specific != NULL)
- return gsymbol->language_specific.cplus_specific->demangled_name;
- else
- return NULL;
- }
- else if (gsymbol->language == language_ada)
+ if (gsymbol->language == language_ada)
{
if (!gsymbol->ada_mangled)
return NULL;
struct obstack *obstack)
{
gsymbol->language = language;
- if (gsymbol->language == language_d
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_d
|| gsymbol->language == language_go
|| gsymbol->language == language_java
|| gsymbol->language == language_objc
gdb_assert (gsymbol->ada_mangled == 0);
gsymbol->language_specific.obstack = obstack;
}
- else if (gsymbol->language == language_cplus)
- gsymbol->language_specific.cplus_specific = NULL;
else
{
memset (&gsymbol->language_specific, 0,
ALL_OBJFILES (objfile)
{
- struct symtab *s = NULL;
+ struct compunit_symtab *cust = NULL;
if (objfile->sf)
- s = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol,
- pc, section, 0);
- if (s != NULL)
+ cust = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile, msymbol,
+ pc, section, 0);
+ if (cust)
return;
}
}
if (!sym)
return NULL;
+ if (!SYMBOL_OBJFILE_OWNED (sym))
+ return sym;
+
/* We either have an OBJFILE, or we can get at it from the sym's
symtab. Anything else is a bug. */
- gdb_assert (objfile || SYMBOL_SYMTAB (sym));
+ gdb_assert (objfile || symbol_symtab (sym));
if (objfile == NULL)
- objfile = SYMBOL_OBJFILE (sym);
+ objfile = symbol_objfile (sym);
if (SYMBOL_OBJ_SECTION (objfile, sym))
return sym;
if (lang->la_name_of_this == NULL || block == NULL)
return NULL;
+ if (symbol_lookup_debug > 1)
+ {
+ struct objfile *objfile = lookup_objfile_from_block (block);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_language_this (%s, %s (objfile %s))",
+ lang->la_name, host_address_to_string (block),
+ objfile_debug_name (objfile));
+ }
+
while (block)
{
struct symbol *sym;
sym = block_lookup_symbol (block, lang->la_name_of_this, VAR_DOMAIN);
if (sym != NULL)
{
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog, " = %s (%s, block %s)\n",
+ SYMBOL_PRINT_NAME (sym),
+ host_address_to_string (sym),
+ host_address_to_string (block));
+ }
block_found = block;
return sym;
}
block = BLOCK_SUPERBLOCK (block);
}
+ if (symbol_lookup_debug > 1)
+ fprintf_unfiltered (gdb_stdlog, " = NULL\n");
return NULL;
}
struct symbol *sym;
const struct language_defn *langdef;
+ if (symbol_lookup_debug)
+ {
+ struct objfile *objfile = lookup_objfile_from_block (block);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_aux (%s, %s (objfile %s), %s, %s)\n",
+ name, host_address_to_string (block),
+ objfile != NULL
+ ? objfile_debug_name (objfile) : "NULL",
+ domain_name (domain), language_str (language));
+ }
+
+ /* Initialize block_found so that the language la_lookup_symbol_nonlocal
+ routines don't have to set it (to NULL) if a primitive type is found.
+ We do this early so that block_found is also NULL if no symbol is
+ found (though this is not part of the API, and callers cannot assume
+ this). */
+ block_found = NULL;
+
/* Make sure we do something sensible with is_a_field_of_this, since
the callers that set this parameter to some non-null value will
certainly use it later. If we don't set it, the contents of
sym = lookup_local_symbol (name, block, domain, language);
if (sym != NULL)
- return sym;
+ {
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
+ host_address_to_string (sym));
+ }
+ return sym;
+ }
/* If requested to do so by the caller and if appropriate for LANGUAGE,
check to see if NAME is a field of `this'. */
langdef->la_name_of_this);
if (check_field (t, name, is_a_field_of_this))
- return NULL;
+ {
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_aux (...) = NULL\n");
+ }
+ return NULL;
+ }
}
}
/* Now do whatever is appropriate for LANGUAGE to look
up static and global variables. */
- sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
+ sym = langdef->la_lookup_symbol_nonlocal (langdef, name, block, domain);
if (sym != NULL)
- return sym;
+ {
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
+ host_address_to_string (sym));
+ }
+ return sym;
+ }
/* Now search all static file-level symbols. Not strictly correct,
but more useful than an error. */
- return lookup_static_symbol (name, domain);
+ sym = lookup_static_symbol (name, domain);
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
+ sym != NULL ? host_address_to_string (sym) : "NULL");
+ }
+ return sym;
}
/* Check to see if the symbol is defined in BLOCK or its superiors.
lookup_objfile_from_block (const struct block *block)
{
struct objfile *obj;
- struct symtab *s;
+ struct compunit_symtab *cust;
if (block == NULL)
return NULL;
block = block_global_block (block);
- /* Go through SYMTABS.
- Non-primary symtabs share the block vector with their primary symtabs
- so we use ALL_PRIMARY_SYMTABS here instead of ALL_SYMTABS. */
- ALL_PRIMARY_SYMTABS (obj, s)
- if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
+ /* Look through all blockvectors. */
+ ALL_COMPUNITS (obj, cust)
+ if (block == BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
+ GLOBAL_BLOCK))
{
if (obj->separate_debug_objfile_backlink)
obj = obj->separate_debug_objfile_backlink;
{
struct symbol *sym;
+ if (symbol_lookup_debug > 1)
+ {
+ struct objfile *objfile = lookup_objfile_from_block (block);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_block (%s, %s (objfile %s), %s)",
+ name, host_address_to_string (block),
+ objfile_debug_name (objfile),
+ domain_name (domain));
+ }
+
sym = block_lookup_symbol (block, name, domain);
if (sym)
{
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog, " = %s\n",
+ host_address_to_string (sym));
+ }
block_found = block;
return fixup_symbol_section (sym, NULL);
}
+ if (symbol_lookup_debug > 1)
+ fprintf_unfiltered (gdb_stdlog, " = NULL\n");
return NULL;
}
/* See symtab.h. */
struct symbol *
-lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
+lookup_global_symbol_from_objfile (struct objfile *main_objfile,
const char *name,
const domain_enum domain)
{
- const struct objfile *objfile;
- struct symbol *sym;
- const struct blockvector *bv;
- const struct block *block;
- struct symtab *s;
+ struct objfile *objfile;
for (objfile = main_objfile;
objfile;
objfile = objfile_separate_debug_iterate (main_objfile, objfile))
{
- /* Go through symtabs. */
- ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = block_lookup_symbol (block, name, domain);
- if (sym)
- {
- block_found = block;
- return fixup_symbol_section (sym, (struct objfile *)objfile);
- }
- }
+ struct symbol *sym = lookup_symbol_in_objfile (objfile, GLOBAL_BLOCK,
+ name, domain);
- sym = lookup_symbol_via_quick_fns ((struct objfile *) objfile,
- GLOBAL_BLOCK, name, domain);
- if (sym)
+ if (sym != NULL)
return sym;
}
lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
const char *name, const domain_enum domain)
{
- struct symbol *sym = NULL;
- const struct blockvector *bv;
- const struct block *block;
- struct symtab *s;
+ struct compunit_symtab *cust;
+
+ gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
- ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+ if (symbol_lookup_debug > 1)
{
- bv = BLOCKVECTOR (s);
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_objfile_symtabs (%s, %s, %s, %s)",
+ objfile_debug_name (objfile),
+ block_index == GLOBAL_BLOCK
+ ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+ name, domain_name (domain));
+ }
+
+ ALL_OBJFILE_COMPUNITS (objfile, cust)
+ {
+ const struct blockvector *bv;
+ const struct block *block;
+ struct symbol *sym;
+
+ bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, block_index);
- sym = block_lookup_symbol (block, name, domain);
+ sym = block_lookup_symbol_primary (block, name, domain);
if (sym)
{
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n",
+ host_address_to_string (sym),
+ host_address_to_string (block));
+ }
block_found = block;
return fixup_symbol_section (sym, objfile);
}
}
+ if (symbol_lookup_debug > 1)
+ fprintf_unfiltered (gdb_stdlog, " = NULL\n");
return NULL;
}
/* Wrapper around lookup_symbol_in_objfile_symtabs for search_symbols.
Look up LINKAGE_NAME in DOMAIN in the global and static blocks of OBJFILE
- and all related objfiles. */
+ and all associated separate debug objfiles.
+
+ Normally we only look in OBJFILE, and not any separate debug objfiles
+ because the outer loop will cause them to be searched too. This case is
+ different. Here we're called from search_symbols where it will only
+ call us for the the objfile that contains a matching minsym. */
static struct symbol *
lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
static void ATTRIBUTE_NORETURN
error_in_psymtab_expansion (int block_index, const char *name,
- struct symtab *symtab)
+ struct compunit_symtab *cust)
{
error (_("\
Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n \
(if a template, try specifying an instantiation: %s<type>)."),
block_index == GLOBAL_BLOCK ? "global" : "static",
- name, symtab_to_filename_for_display (symtab), name, name);
+ name,
+ symtab_to_filename_for_display (compunit_primary_filetab (cust)),
+ name, name);
}
/* A helper function for various lookup routines that interfaces with
lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index,
const char *name, const domain_enum domain)
{
- struct symtab *symtab;
+ struct compunit_symtab *cust;
const struct blockvector *bv;
const struct block *block;
struct symbol *sym;
if (!objfile->sf)
return NULL;
- symtab = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
- if (!symtab)
- return NULL;
- bv = BLOCKVECTOR (symtab);
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_via_quick_fns (%s, %s, %s, %s)\n",
+ objfile_debug_name (objfile),
+ block_index == GLOBAL_BLOCK
+ ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+ name, domain_name (domain));
+ }
+
+ cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
+ if (cust == NULL)
+ {
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_via_quick_fns (...) = NULL\n");
+ }
+ return NULL;
+ }
+
+ bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_lookup_symbol (block, name, domain);
if (!sym)
- error_in_psymtab_expansion (block_index, name, symtab);
+ error_in_psymtab_expansion (block_index, name, cust);
+
+ if (symbol_lookup_debug > 1)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_via_quick_fns (...) = %s (block %s)\n",
+ host_address_to_string (sym),
+ host_address_to_string (block));
+ }
+
block_found = block;
return fixup_symbol_section (sym, objfile);
}
/* See symtab.h. */
struct symbol *
-basic_lookup_symbol_nonlocal (const char *name,
+basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
+ const char *name,
const struct block *block,
const domain_enum domain)
{
if (sym != NULL)
return sym;
+ /* If we didn't find a definition for a builtin type in the static block,
+ search for it now. This is actually the right thing to do and can be
+ a massive performance win. E.g., when debugging a program with lots of
+ shared libraries we could search all of them only to find out the
+ builtin type isn't defined in any of them. This is common for types
+ like "void". */
+ if (domain == VAR_DOMAIN)
+ {
+ struct gdbarch *gdbarch;
+
+ if (block == NULL)
+ gdbarch = target_gdbarch ();
+ else
+ gdbarch = block_gdbarch (block);
+ sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name);
+ if (sym != NULL)
+ return sym;
+ }
+
return lookup_global_symbol (name, block, domain);
}
const domain_enum domain)
{
const struct block *static_block = block_static_block (block);
+ struct symbol *sym;
- if (static_block != NULL)
- return lookup_symbol_in_block (name, static_block, domain);
- else
+ if (static_block == NULL)
return NULL;
+
+ if (symbol_lookup_debug)
+ {
+ struct objfile *objfile = lookup_objfile_from_block (static_block);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_static_block (%s, %s (objfile %s),"
+ " %s)\n",
+ name,
+ host_address_to_string (block),
+ objfile_debug_name (objfile),
+ domain_name (domain));
+ }
+
+ sym = lookup_symbol_in_block (name, static_block, domain);
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_static_block (...) = %s\n",
+ sym != NULL ? host_address_to_string (sym) : "NULL");
+ }
+ return sym;
}
/* Perform the standard symbol lookup of NAME in OBJFILE:
{
struct symbol *result;
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_objfile (%s, %s, %s, %s)\n",
+ objfile_debug_name (objfile),
+ block_index == GLOBAL_BLOCK
+ ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+ name, domain_name (domain));
+ }
+
result = lookup_symbol_in_objfile_symtabs (objfile, block_index,
name, domain);
- if (result == NULL)
+ if (result != NULL)
{
- result = lookup_symbol_via_quick_fns (objfile, block_index,
- name, domain);
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_objfile (...) = %s"
+ " (in symtabs)\n",
+ host_address_to_string (result));
+ }
+ return result;
}
+ result = lookup_symbol_via_quick_fns (objfile, block_index,
+ name, domain);
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "lookup_symbol_in_objfile (...) = %s%s\n",
+ result != NULL
+ ? host_address_to_string (result)
+ : "NULL",
+ result != NULL ? " (via quick fns)" : "");
+ }
return result;
}
basic_lookup_transparent_type_quick (struct objfile *objfile, int block_index,
const char *name)
{
- struct symtab *symtab;
+ struct compunit_symtab *cust;
const struct blockvector *bv;
struct block *block;
struct symbol *sym;
if (!objfile->sf)
return NULL;
- symtab = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
- STRUCT_DOMAIN);
- if (!symtab)
+ cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
+ STRUCT_DOMAIN);
+ if (cust == NULL)
return NULL;
- bv = BLOCKVECTOR (symtab);
+ bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
if (!sym)
- error_in_psymtab_expansion (block_index, name, symtab);
+ error_in_psymtab_expansion (block_index, name, cust);
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
return SYMBOL_TYPE (sym);
basic_lookup_transparent_type (const char *name)
{
struct symbol *sym;
- struct symtab *s = NULL;
+ struct compunit_symtab *cust;
const struct blockvector *bv;
struct objfile *objfile;
struct block *block;
ALL_OBJFILES (objfile)
{
- ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+ ALL_OBJFILE_COMPUNITS (objfile, cust)
{
- bv = BLOCKVECTOR (s);
+ bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
ALL_OBJFILES (objfile)
{
- ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+ ALL_OBJFILE_COMPUNITS (objfile, cust)
{
- bv = BLOCKVECTOR (s);
+ bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
}
}
-/* Find the symtab associated with PC and SECTION. Look through the
- psymtabs and read in another symtab if necessary. */
+/* Find the compunit symtab associated with PC and SECTION.
+ This will read in debug info as necessary. */
-struct symtab *
-find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
+struct compunit_symtab *
+find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
{
- struct block *b;
- const struct blockvector *bv;
- struct symtab *s = NULL;
- struct symtab *best_s = NULL;
+ struct compunit_symtab *cust;
+ struct compunit_symtab *best_cust = NULL;
struct objfile *objfile;
CORE_ADDR distance = 0;
struct bound_minimal_symbol msymbol;
It also happens for objfiles that have their functions reordered.
For these, the symtab we are looking for is not necessarily read in. */
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
- bv = BLOCKVECTOR (s);
+ struct block *b;
+ const struct blockvector *bv;
+
+ bv = COMPUNIT_BLOCKVECTOR (cust);
b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
if (BLOCK_START (b) <= pc
can't be found. */
if ((objfile->flags & OBJF_REORDERED) && objfile->sf)
{
- struct symtab *result;
+ struct compunit_symtab *result;
result
- = objfile->sf->qf->find_pc_sect_symtab (objfile,
- msymbol,
- pc, section,
- 0);
- if (result)
+ = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
+ msymbol,
+ pc, section,
+ 0);
+ if (result != NULL)
return result;
}
if (section != 0)
section. */
}
distance = BLOCK_END (b) - BLOCK_START (b);
- best_s = s;
+ best_cust = cust;
}
}
- if (best_s != NULL)
- return (best_s);
+ if (best_cust != NULL)
+ return best_cust;
/* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs). */
ALL_OBJFILES (objfile)
{
- struct symtab *result;
+ struct compunit_symtab *result;
if (!objfile->sf)
continue;
- result = objfile->sf->qf->find_pc_sect_symtab (objfile,
- msymbol,
- pc, section,
- 1);
- if (result)
+ result = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
+ msymbol,
+ pc, section,
+ 1);
+ if (result != NULL)
return result;
}
return NULL;
}
-/* Find the symtab associated with PC. Look through the psymtabs and read
- in another symtab if necessary. Backward compatibility, no section. */
+/* Find the compunit symtab associated with PC.
+ This will read in debug info as necessary.
+ Backward compatibility, no section. */
-struct symtab *
-find_pc_symtab (CORE_ADDR pc)
+struct compunit_symtab *
+find_pc_compunit_symtab (CORE_ADDR pc)
{
- return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+ return find_pc_sect_compunit_symtab (pc, find_pc_mapped_section (pc));
}
\f
struct symtab_and_line
find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
{
- struct symtab *s;
+ struct compunit_symtab *cust;
+ struct symtab *iter_s;
struct linetable *l;
int len;
int i;
struct symtab_and_line val;
const struct blockvector *bv;
struct bound_minimal_symbol msymbol;
- struct objfile *objfile;
/* Info on best line seen so far, and where it starts, and its file. */
}
- s = find_pc_sect_symtab (pc, section);
- if (!s)
+ cust = find_pc_sect_compunit_symtab (pc, section);
+ if (cust == NULL)
{
/* If no symbol information, return previous pc. */
if (notcurrent)
return val;
}
- bv = BLOCKVECTOR (s);
- objfile = SYMTAB_OBJFILE (s);
+ bv = COMPUNIT_BLOCKVECTOR (cust);
/* Look at all the symtabs that share this blockvector.
They all have the same apriori range, that we found was right;
but they have different line tables. */
- ALL_OBJFILE_SYMTABS (objfile, s)
+ ALL_COMPUNIT_FILETABS (cust, iter_s)
{
- if (BLOCKVECTOR (s) != bv)
- continue;
-
/* Find the best line in this symtab. */
- l = LINETABLE (s);
+ l = SYMTAB_LINETABLE (iter_s);
if (!l)
continue;
len = l->nitems;
if (prev && prev->line && (!best || prev->pc > best->pc))
{
best = prev;
- best_symtab = s;
+ best_symtab = iter_s;
/* Discard BEST_END if it's before the PC of the current BEST. */
if (best_end <= best->pc)
struct symtab *best_symtab;
/* First try looking it up in the given symtab. */
- best_linetable = LINETABLE (symtab);
+ best_linetable = SYMTAB_LINETABLE (symtab);
best_symtab = symtab;
best_index = find_line_common (best_linetable, line, &exact, 0);
if (best_index < 0 || !exact)
int best;
struct objfile *objfile;
+ struct compunit_symtab *cu;
struct symtab *s;
if (best_index >= 0)
symtab_to_fullname (symtab));
}
- ALL_SYMTABS (objfile, s)
+ ALL_FILETABS (objfile, cu, s)
{
struct linetable *l;
int ind;
if (FILENAME_CMP (symtab_to_fullname (symtab),
symtab_to_fullname (s)) != 0)
continue;
- l = LINETABLE (s);
+ l = SYMTAB_LINETABLE (s);
ind = find_line_common (l, line, &exact, 0);
if (ind >= 0)
{
int was_exact;
int idx;
- idx = find_line_common (LINETABLE (symtab), line, &was_exact, start);
+ idx = find_line_common (SYMTAB_LINETABLE (symtab), line, &was_exact,
+ start);
if (idx < 0)
break;
if (!was_exact)
{
- struct linetable_entry *item = &LINETABLE (symtab)->item[idx];
+ struct linetable_entry *item = &SYMTAB_LINETABLE (symtab)->item[idx];
if (*best_item == NULL || item->line < (*best_item)->line)
*best_item = item;
break;
}
- VEC_safe_push (CORE_ADDR, result, LINETABLE (symtab)->item[idx].pc);
+ VEC_safe_push (CORE_ADDR, result,
+ SYMTAB_LINETABLE (symtab)->item[idx].pc);
start = idx + 1;
}
symtab = find_line_symtab (symtab, line, &ind, NULL);
if (symtab != NULL)
{
- l = LINETABLE (symtab);
+ l = SYMTAB_LINETABLE (symtab);
*pc = l->item[ind].pc;
return 1;
}
find_function_start_sal (struct symbol *sym, int funfirstline)
{
struct symtab_and_line sal;
+ struct obj_section *section;
fixup_symbol_section (sym, NULL);
- sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
- SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym), 0);
+ section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
+ sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), section, 0);
/* We always should have a line for the function start address.
If we don't, something is odd. Create a plain SAL refering
init_sal (&sal);
sal.pspace = current_program_space;
sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- sal.section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym);
+ sal.section = section;
}
if (funfirstline)
int i;
/* Give up if this symbol has no lineinfo table. */
- l = LINETABLE (symtab);
+ l = SYMTAB_LINETABLE (symtab);
if (l == NULL)
return func_addr;
{
fixup_symbol_section (sym, NULL);
+ objfile = symbol_objfile (sym);
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym);
+ section = SYMBOL_OBJ_SECTION (objfile, sym);
name = SYMBOL_LINKAGE_NAME (sym);
- objfile = SYMBOL_OBJFILE (sym);
}
else
{
/* Be conservative - allow direct PC (without skipping prologue) only if we
have proven the CU (Compilation Unit) supports it. sal->SYMTAB does not
have to be set by the caller so we use SYM instead. */
- if (sym && SYMBOL_SYMTAB (sym)->locations_valid)
+ if (sym != NULL
+ && COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (symbol_symtab (sym))))
force_skip = 0;
saved_pc = pc;
is aligned. */
if (!force_skip && sym && start_sal.symtab == NULL)
{
- pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
+ pc = skip_prologue_using_lineinfo (pc, symbol_symtab (sym));
/* Recalculate the line number. */
start_sal = find_pc_sect_line (pc, section, 0);
}
&& SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0)
{
sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
- sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block));
+ sal->symtab = symbol_symtab (BLOCK_FUNCTION (function_block));
}
}
do this. */
if (prologue_sal.symtab->language != language_asm)
{
- struct linetable *linetable = LINETABLE (prologue_sal.symtab);
+ struct linetable *linetable = SYMTAB_LINETABLE (prologue_sal.symtab);
int idx = 0;
/* Skip any earlier lines, and any end-of-sequence marker
static void
sources_info (char *ignore, int from_tty)
{
+ struct compunit_symtab *cu;
struct symtab *s;
struct objfile *objfile;
struct output_source_filename_data data;
printf_filtered ("Source files for which symbols have been read in:\n\n");
data.first = 1;
- ALL_SYMTABS (objfile, s)
+ ALL_FILETABS (objfile, cu, s)
{
const char *fullname = symtab_to_fullname (s);
struct symbol_search *sym_b = *(struct symbol_search **) sb;
int c;
- c = FILENAME_CMP (sym_a->symtab->filename, sym_b->symtab->filename);
+ c = FILENAME_CMP (symbol_symtab (sym_a->symbol)->filename,
+ symbol_symtab (sym_b->symbol)->filename);
if (c != 0)
return c;
int nfiles, const char *files[],
struct symbol_search **matches)
{
- struct symtab *s;
+ struct compunit_symtab *cust;
const struct blockvector *bv;
struct block *b;
int i = 0;
{
/* Note: An important side-effect of these lookup functions
is to expand the symbol table if msymbol is found, for the
- benefit of the next loop on ALL_PRIMARY_SYMTABS. */
+ benefit of the next loop on ALL_COMPUNITS. */
if (kind == FUNCTIONS_DOMAIN
- ? find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
- msymbol)) == NULL
+ ? (find_pc_compunit_symtab
+ (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL)
: (lookup_symbol_in_objfile_from_linkage_name
(objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
== NULL))
nfound = 0;
retval_chain = make_cleanup_free_search_symbols (&found);
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
- bv = BLOCKVECTOR (s);
+ bv = COMPUNIT_BLOCKVECTOR (cust);
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
b = BLOCKVECTOR_BLOCK (bv, i);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- struct symtab *real_symtab = SYMBOL_SYMTAB (sym);
+ struct symtab *real_symtab = symbol_symtab (sym);
QUIT;
e.g., c++ static const members.
We only want to skip enums here. */
&& !(SYMBOL_CLASS (sym) == LOC_CONST
- && TYPE_CODE (SYMBOL_TYPE (sym))
- == TYPE_CODE_ENUM))
+ && (TYPE_CODE (SYMBOL_TYPE (sym))
+ == TYPE_CODE_ENUM)))
|| (kind == FUNCTIONS_DOMAIN
&& SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (kind == TYPES_DOMAIN
struct symbol_search *psr = (struct symbol_search *)
xmalloc (sizeof (struct symbol_search));
psr->block = i;
- psr->symtab = real_symtab;
psr->symbol = sym;
memset (&psr->msymbol, 0, sizeof (psr->msymbol));
psr->next = NULL;
}
/* If there are no eyes, avoid all contact. I mean, if there are
- no debug symbols, then print directly from the msymbol_vector. */
+ no debug symbols, then add matching minsyms. */
if (found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
{
/* For functions we can do a quick check of whether the
symbol might be found via find_pc_symtab. */
if (kind != FUNCTIONS_DOMAIN
- || find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
- msymbol)) == NULL)
+ || (find_pc_compunit_symtab
+ (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL))
{
if (lookup_symbol_in_objfile_from_linkage_name
(objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
psr->block = i;
psr->msymbol.minsym = msymbol;
psr->msymbol.objfile = objfile;
- psr->symtab = NULL;
psr->symbol = NULL;
psr->next = NULL;
if (tail == NULL)
static void
print_symbol_info (enum search_domain kind,
- struct symtab *s, struct symbol *sym,
+ struct symbol *sym,
int block, const char *last)
{
+ struct symtab *s = symbol_symtab (sym);
const char *s_filename = symtab_to_filename_for_display (s);
if (last == NULL || filename_cmp (last, s_filename) != 0)
else
{
print_symbol_info (kind,
- p->symtab,
p->symbol,
p->block,
last_filename);
- last_filename = symtab_to_filename_for_display (p->symtab);
+ last_filename
+ = symtab_to_filename_for_display (symbol_symtab (p->symbol));
}
}
{
if (p->msymbol.minsym == NULL)
{
- const char *fullname = symtab_to_fullname (p->symtab);
+ struct symtab *symtab = symbol_symtab (p->symbol);
+ const char *fullname = symtab_to_fullname (symtab);
int newlen = (strlen (fullname)
+ strlen (SYMBOL_LINKAGE_NAME (p->symbol))
strcat (string, "'");
break_command (string, from_tty);
print_symbol_info (FUNCTIONS_DOMAIN,
- p->symtab,
p->symbol,
p->block,
- symtab_to_filename_for_display (p->symtab));
+ symtab_to_filename_for_display (symtab));
}
else
{
won't be that many. */
struct symbol *sym;
- struct symtab *s;
+ struct compunit_symtab *cust;
struct minimal_symbol *msymbol;
struct objfile *objfile;
const struct block *b;
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
if (code == TYPE_CODE_UNDEF
}
}
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_COMPUNITS (objfile, cust)
{
QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
if (code == TYPE_CODE_UNDEF
/* Go through this symtab and check the externs and statics for
symbols which match. */
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ b = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), GLOBAL_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ b = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), STATIC_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
VEC (char_ptr) *
make_source_files_completion_list (const char *text, const char *word)
{
+ struct compunit_symtab *cu;
struct symtab *s;
struct objfile *objfile;
size_t text_len = strlen (text);
cache_cleanup = make_cleanup (delete_filename_seen_cache,
filename_seen_cache);
- ALL_SYMTABS (objfile, s)
+ ALL_FILETABS (objfile, cu, s)
{
if (not_interesting_fname (s->filename))
continue;
\f
-/* Initialize the symbol SYM. */
+/* Helper function to initialize the fields of an objfile-owned symbol.
+ It assumed that *SYM is already all zeroes. */
+
+static void
+initialize_objfile_symbol_1 (struct symbol *sym)
+{
+ SYMBOL_OBJFILE_OWNED (sym) = 1;
+ SYMBOL_SECTION (sym) = -1;
+}
+
+/* Initialize the symbol SYM, and mark it as being owned by an objfile. */
void
-initialize_symbol (struct symbol *sym)
+initialize_objfile_symbol (struct symbol *sym)
{
memset (sym, 0, sizeof (*sym));
- SYMBOL_SECTION (sym) = -1;
+ initialize_objfile_symbol_1 (sym);
}
/* Allocate and initialize a new 'struct symbol' on OBJFILE's
struct symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
- SYMBOL_SECTION (result) = -1;
+ initialize_objfile_symbol_1 (result);
return result;
}
struct template_symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
- SYMBOL_SECTION (&result->base) = -1;
+ initialize_objfile_symbol_1 (&result->base);
return result;
}
+/* See symtab.h. */
+
+struct objfile *
+symbol_objfile (const struct symbol *symbol)
+{
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ return SYMTAB_OBJFILE (symbol->owner.symtab);
+}
+
+/* See symtab.h. */
+
+struct gdbarch *
+symbol_arch (const struct symbol *symbol)
+{
+ if (!SYMBOL_OBJFILE_OWNED (symbol))
+ return symbol->owner.arch;
+ return get_objfile_arch (SYMTAB_OBJFILE (symbol->owner.symtab));
+}
+
+/* See symtab.h. */
+
+struct symtab *
+symbol_symtab (const struct symbol *symbol)
+{
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ return symbol->owner.symtab;
+}
+
+/* See symtab.h. */
+
+void
+symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
+{
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ symbol->owner.symtab = symtab;
+}
+
\f
void
NULL,
&setdebuglist, &showdebuglist);
+ add_setshow_zuinteger_cmd ("symbol-lookup", no_class, &symbol_lookup_debug,
+ _("\
+Set debugging of symbol lookup."), _("\
+Show debugging of symbol lookup."), _("\
+When enabled (non-zero), symbol lookups are logged."),
+ NULL, NULL,
+ &setdebuglist, &showdebuglist);
+
observer_attach_executable_changed (symtab_observer_executable_changed);
}