/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2013 Free Software Foundation, Inc.
+ Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include <sys/types.h>
#include <fcntl.h>
-#include "gdb_string.h"
-#include "gdb_stat.h"
+#include <string.h>
+#include <sys/stat.h>
#include <ctype.h>
#include "cp-abi.h"
#include "cp-support.h"
#include "macrotab.h"
#include "macroscope.h"
-#include "psymtab.h"
#include "parser-defs.h"
/* Prototypes for local functions */
/* */
+/* Program space key for finding name and language of "main". */
+
+static const struct program_space_data *main_progspace_key;
+
+/* Type of the data stored on the program space. */
+
+struct main_info
+{
+ /* Name of "main". */
+
+ char *name_of_main;
+
+ /* Language of "main". */
+
+ enum language language_of_main;
+};
+
/* When non-zero, print debugging messages related to symtab creation. */
-int symtab_create_debug = 0;
+unsigned int symtab_create_debug = 0;
/* Non-zero if a file may be known by two different basenames.
This is the uncommon case, and significantly slows down gdb.
}
}
+/* Set the primary field in SYMTAB. */
+
+void
+set_symtab_primary (struct symtab *symtab, int primary)
+{
+ symtab->primary = primary;
+
+ 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));
+ }
+}
+
/* See whether FILENAME matches SEARCH_NAME using the rule that we
advertise to the user. (The manual's description of linespecs
describes what we advertise). Returns true if they match, false
Choosing a much larger table size wastes memory, and saves only about
1% in symbol reading. */
- objfile->demangled_names_hash = htab_create_alloc
+ objfile->per_bfd->demangled_names_hash = htab_create_alloc
(256, hash_demangled_name_entry, eq_demangled_name_entry,
NULL, xcalloc, xfree);
}
symbols). Just the mangling standard is not standardized across compilers
and there is no DW_AT_producer available for inferiors with only the ELF
symbols to check the mangling kind. */
+
+ /* Check for Ada symbols last. See comment below explaining why. */
+
+ if (gsymbol->language == language_auto)
+ {
+ const char *demangled = ada_decode (mangled);
+
+ if (demangled != mangled && demangled != NULL && demangled[0] != '<')
+ {
+ /* Set the gsymbol language to Ada, but still return NULL.
+ Two reasons for that:
+
+ 1. For Ada, we prefer computing the symbol's decoded name
+ on the fly rather than pre-compute it, in order to save
+ memory (Ada projects are typically very large).
+
+ 2. There are some areas in the definition of the GNAT
+ encoding where, with a bit of bad luck, we might be able
+ to decode a non-Ada symbol, generating an incorrect
+ demangled name (Eg: names ending with "TB" for instance
+ are identified as task bodies and so stripped from
+ the decoded name returned).
+
+ Returning NULL, here, helps us get a little bit of
+ the best of both worlds. Because we're last, we should
+ not affect any of the other languages that were able to
+ demangle the symbol before us; we get to correctly tag
+ Ada symbols as such; and even if we incorrectly tagged
+ a non-Ada symbol, which should be rare, any routing
+ through the Ada language should be transparent (Ada
+ tries to behave much like C/C++ with non-Ada symbols). */
+ gsymbol->language = language_ada;
+ return NULL;
+ }
+ }
+
return NULL;
}
objfile), and it will not be copied.
The hash table corresponding to OBJFILE is used, and the memory
- comes from that objfile's objfile_obstack. LINKAGE_NAME is copied,
+ comes from the per-BFD storage_obstack. LINKAGE_NAME is copied,
so the pointer can be discarded after calling this function. */
/* We have to be careful when dealing with Java names: when we run
/* The length of lookup_name. */
int lookup_len;
struct demangled_name_entry entry;
+ struct objfile_per_bfd_storage *per_bfd = objfile->per_bfd;
if (gsymbol->language == language_ada)
{
gsymbol->name = linkage_name;
else
{
- char *name = obstack_alloc (&objfile->objfile_obstack, len + 1);
+ char *name = obstack_alloc (&per_bfd->storage_obstack, len + 1);
memcpy (name, linkage_name, len);
name[len] = '\0';
gsymbol->name = name;
}
- symbol_set_demangled_name (gsymbol, NULL, &objfile->objfile_obstack);
+ symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
return;
}
- if (objfile->demangled_names_hash == NULL)
+ if (per_bfd->demangled_names_hash == NULL)
create_demangled_names_hash (objfile);
/* The stabs reader generally provides names that are not
entry.mangled = lookup_name;
slot = ((struct demangled_name_entry **)
- htab_find_slot (objfile->demangled_names_hash,
+ htab_find_slot (per_bfd->demangled_names_hash,
&entry, INSERT));
/* If this name is not in the hash table, add it. */
us better bcache hit rates for partial symbols. */
if (!copy_name && lookup_name == linkage_name)
{
- *slot = obstack_alloc (&objfile->objfile_obstack,
+ *slot = obstack_alloc (&per_bfd->storage_obstack,
offsetof (struct demangled_name_entry,
demangled)
+ demangled_len + 1);
/* If we must copy the mangled name, put it directly after
the demangled name so we can have a single
allocation. */
- *slot = obstack_alloc (&objfile->objfile_obstack,
+ *slot = obstack_alloc (&per_bfd->storage_obstack,
offsetof (struct demangled_name_entry,
demangled)
+ lookup_len + demangled_len + 2);
gsymbol->name = (*slot)->mangled + lookup_len - len;
if ((*slot)->demangled[0] != '\0')
symbol_set_demangled_name (gsymbol, (*slot)->demangled,
- &objfile->objfile_obstack);
+ &per_bfd->storage_obstack);
else
- symbol_set_demangled_name (gsymbol, NULL, &objfile->objfile_obstack);
+ symbol_set_demangled_name (gsymbol, NULL, &per_bfd->storage_obstack);
}
/* Return the source code name of a symbol. In languages where
clear_filename_seen_cache (data.filename_seen_cache);
data.first = 1;
- map_partial_symbol_filenames (output_partial_symbol_filename, &data,
- 1 /*need_fullname*/);
+ map_symbol_filenames (output_partial_symbol_filename, &data,
+ 1 /*need_fullname*/);
printf_filtered ("\n");
do_cleanups (cleanups);
struct symbol_search *sym_b = *(struct symbol_search **) sb;
int c;
- c = strcmp (sym_a->symtab->filename, sym_b->symtab->filename);
+ c = FILENAME_CMP (sym_a->symtab->filename, sym_b->symtab->filename);
if (c != 0)
return c;
SYMBOL_PRINT_NAME (sym_b->symbol));
}
-/* Helper function for sort_search_symbols_remove_dups.
- Return TRUE if symbols A, B are equal. */
-
-static int
-search_symbols_equal (const struct symbol_search *a,
- const struct symbol_search *b)
-{
- return (strcmp (a->symtab->filename, b->symtab->filename) == 0
- && a->block == b->block
- && strcmp (SYMBOL_PRINT_NAME (a->symbol),
- SYMBOL_PRINT_NAME (b->symbol)) == 0);
-}
-
/* Sort the NFOUND symbols in list FOUND and remove duplicates.
The duplicates are freed, and the new list is returned in
*NEW_HEAD, *NEW_TAIL. */
/* Collapse out the dups. */
for (i = 1, j = 1; i < nfound; ++i)
{
- if (! search_symbols_equal (symbols[j - 1], symbols[i]))
+ if (compare_search_syms (&symbols[j - 1], &symbols[i]) != 0)
symbols[j++] = symbols[i];
else
xfree (symbols[i]);
datum.nfiles = nfiles;
datum.files = files;
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile,
- (nfiles == 0
- ? NULL
- : search_symbols_file_matches),
- search_symbols_name_matches,
- kind,
- &datum);
- }
+ expand_symtabs_matching ((nfiles == 0
+ ? NULL
+ : search_symbols_file_matches),
+ search_symbols_name_matches,
+ kind, &datum);
/* Here, we search through the minimal symbol tables for functions
and variables that match, and force their symbols to be read.
}
/* Type of the user_data argument passed to add_macro_name or
- expand_partial_symbol_name. The contents are simply whatever is
+ symbol_completion_matcher. The contents are simply whatever is
needed by completion_list_add_name. */
struct add_name_data
{
datum->text, datum->word);
}
-/* A callback for expand_partial_symbol_names. */
+/* A callback for expand_symtabs_matching. */
static int
-expand_partial_symbol_name (const char *name, void *user_data)
+symbol_completion_matcher (const char *name, void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
/* Look through the partial symtabs for all symbols which begin
by matching SYM_TEXT. Expand all CUs that you find to the list.
The real names will get added by COMPLETION_LIST_ADD_SYMBOL below. */
- expand_partial_symbol_names (expand_partial_symbol_name, &datum);
+ expand_symtabs_matching (NULL, symbol_completion_matcher, ALL_DOMAIN,
+ &datum);
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list. Eventually we want to ignore
datum.word = word;
datum.text_len = text_len;
datum.list = &list;
- map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
- 0 /*need_fullname*/);
+ map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
+ 0 /*need_fullname*/);
do_cleanups (cache_cleanup);
discard_cleanups (back_to);
}
\f
/* Track MAIN */
-static char *name_of_main;
-enum language language_of_main = language_unknown;
-void
-set_main_name (const char *name)
+/* Return the "main_info" object for the current program space. If
+ the object has not yet been created, create it and fill in some
+ default values. */
+
+static struct main_info *
+get_main_info (void)
{
- if (name_of_main != NULL)
+ struct main_info *info = program_space_data (current_program_space,
+ main_progspace_key);
+
+ if (info == NULL)
{
- xfree (name_of_main);
- name_of_main = NULL;
- language_of_main = language_unknown;
+ /* It may seem strange to store the main name in the progspace
+ and also in whatever objfile happens to see a main name in
+ its debug info. The reason for this is mainly historical:
+ gdb returned "main" as the name even if no function named
+ "main" was defined the program; and this approach lets us
+ keep compatibility. */
+ info = XCNEW (struct main_info);
+ info->language_of_main = language_unknown;
+ set_program_space_data (current_program_space, main_progspace_key,
+ info);
+ }
+
+ return info;
+}
+
+/* A cleanup to destroy a struct main_info when a progspace is
+ destroyed. */
+
+static void
+main_info_cleanup (struct program_space *pspace, void *data)
+{
+ struct main_info *info = data;
+
+ if (info != NULL)
+ xfree (info->name_of_main);
+ xfree (info);
+}
+
+static void
+set_main_name (const char *name, enum language lang)
+{
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main != NULL)
+ {
+ xfree (info->name_of_main);
+ info->name_of_main = NULL;
+ info->language_of_main = language_unknown;
}
if (name != NULL)
{
- name_of_main = xstrdup (name);
- language_of_main = language_unknown;
+ info->name_of_main = xstrdup (name);
+ info->language_of_main = lang;
}
}
find_main_name (void)
{
const char *new_main_name;
+ struct objfile *objfile;
+
+ /* First check the objfiles to see whether a debuginfo reader has
+ picked up the appropriate main name. Historically the main name
+ was found in a more or less random way; this approach instead
+ relies on the order of objfile creation -- which still isn't
+ guaranteed to get the correct answer, but is just probably more
+ accurate. */
+ ALL_OBJFILES (objfile)
+ {
+ if (objfile->per_bfd->name_of_main != NULL)
+ {
+ set_main_name (objfile->per_bfd->name_of_main,
+ objfile->per_bfd->language_of_main);
+ return;
+ }
+ }
/* Try to see if the main procedure is in Ada. */
/* FIXME: brobecker/2005-03-07: Another way of doing this would
new_main_name = ada_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_ada);
return;
}
new_main_name = go_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_go);
return;
}
new_main_name = pascal_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_pascal);
return;
}
/* The languages above didn't identify the name of the main procedure.
Fallback to "main". */
- set_main_name ("main");
+ set_main_name ("main", language_unknown);
}
char *
main_name (void)
{
- if (name_of_main == NULL)
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
find_main_name ();
- return name_of_main;
+ return info->name_of_main;
+}
+
+/* Return the language of the main function. If it is not known,
+ return language_unknown. */
+
+enum language
+main_language (void)
+{
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
+ find_main_name ();
+
+ return info->language_of_main;
}
/* Handle ``executable_changed'' events for the symtab module. */
symtab_observer_executable_changed (void)
{
/* NAME_OF_MAIN may no longer be the same, so reset it for now. */
- set_main_name (NULL);
+ set_main_name (NULL, language_unknown);
}
/* Return 1 if the supplied producer string matches the ARM RealView
{
initialize_ordinary_address_classes ();
+ main_progspace_key
+ = register_program_space_data_with_cleanup (NULL, main_info_cleanup);
+
add_info ("variables", variables_info, _("\
All global and static variable names, or those matching REGEXP."));
if (dbx_commands)
NULL, NULL,
&setlist, &showlist);
- add_setshow_boolean_cmd ("symtab-create", no_class, &symtab_create_debug,
- _("Set debugging of symbol table creation."),
- _("Show debugging of symbol table creation."), _("\
-When enabled, debugging messages are printed when building symbol tables."),
- NULL,
- NULL,
- &setdebuglist, &showdebuglist);
+ add_setshow_zuinteger_cmd ("symtab-create", no_class, &symtab_create_debug,
+ _("Set debugging of symbol table creation."),
+ _("Show debugging of symbol table creation."), _("\
+When enabled (non-zero), debugging messages are printed when building\n\
+symbol tables. A value of 1 (one) normally provides enough information.\n\
+A value greater than 1 provides more verbose information."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
observer_attach_executable_changed (symtab_observer_executable_changed);
}