X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=426326d1066f9e15730d69ada9b285695fbef852;hb=466f643cd93347116a8f462f6d4b2000a677a6de;hp=d39962ec03314d2e59f7ceb2921de27c6938a9f8;hpb=2ee563b53258d390d7446e90a67f465d504ae44c;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/symtab.c b/gdb/symtab.c
index d39962ec03..426326d106 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1,14 +1,14 @@
/* Symbol table lookup for the GNU debugger, GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
- Foundation, Inc.
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see . */
#include "defs.h"
#include "symtab.h"
@@ -38,9 +36,18 @@
#include "demangle.h"
#include "inferior.h"
#include "linespec.h"
+#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
+#include "objc-lang.h"
+#include "ada-lang.h"
+#include "p-lang.h"
+#include "addrmap.h"
+
+#include "hashtab.h"
#include "gdb_obstack.h"
+#include "block.h"
+#include "dictionary.h"
#include
#include
@@ -48,11 +55,12 @@
#include "gdb_stat.h"
#include
#include "cp-abi.h"
-
-/* Prototype for one function in parser-defs.h,
- instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
+#include "cp-support.h"
+#include "observer.h"
+#include "gdb_assert.h"
+#include "solist.h"
+#include "macrotab.h"
+#include "macroscope.h"
/* Prototypes for local functions */
@@ -68,7 +76,7 @@ static void variables_info (char *, int);
static void sources_info (char *, int);
-static void output_source_filename (char *, int *);
+static void output_source_filename (const char *, int *);
static int find_line_common (struct linetable *, int, int *);
@@ -76,63 +84,74 @@ static int find_line_common (struct linetable *, int, int *);
char *operator_chars (char *p, char **end);
-static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
- const char *, int,
- namespace_enum);
-
static struct symbol *lookup_symbol_aux (const char *name,
- const char *mangled_name,
+ const char *linkage_name,
const struct block *block,
- const namespace_enum namespace,
- int *is_a_field_of_this,
- struct symtab **symtab);
-
-
-static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
-
-/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
-/* Signals the presence of objects compiled by HP compilers */
-int hp_som_som_object_present = 0;
-
-static void fixup_section (struct general_symbol_info *, struct objfile *);
+ const domain_enum domain,
+ enum language language,
+ int *is_a_field_of_this);
+
+static
+struct symbol *lookup_symbol_aux_local (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain);
+
+static
+struct symbol *lookup_symbol_aux_symtabs (int block_index,
+ const char *name,
+ const char *linkage_name,
+ const domain_enum domain);
+
+static
+struct symbol *lookup_symbol_aux_psymtabs (int block_index,
+ const char *name,
+ const char *linkage_name,
+ const domain_enum domain);
static int file_matches (char *, char **, int);
-static void print_symbol_info (namespace_enum,
+static void print_symbol_info (domain_enum,
struct symtab *, struct symbol *, int, char *);
static void print_msymbol_info (struct minimal_symbol *);
-static void symtab_symbol_info (char *, namespace_enum, int);
-
-static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+static void symtab_symbol_info (char *, domain_enum, int);
void _initialize_symtab (void);
/* */
-/* The single non-language-specific builtin type */
-struct type *builtin_type_error;
-
-/* Block in which the most recently searched-for symbol was found.
- Might be better to make this a parameter to lookup_symbol and
- value_of_this. */
+/* Allow the user to configure the debugger behavior with respect
+ to multiple-choice menus when more than one symbol matches during
+ a symbol lookup. */
-const struct block *block_found;
+const char multiple_symbols_ask[] = "ask";
+const char multiple_symbols_all[] = "all";
+const char multiple_symbols_cancel[] = "cancel";
+static const char *multiple_symbols_modes[] =
+{
+ multiple_symbols_ask,
+ multiple_symbols_all,
+ multiple_symbols_cancel,
+ NULL
+};
+static const char *multiple_symbols_mode = multiple_symbols_all;
-/* While the C++ support is still in flux, issue a possibly helpful hint on
- using the new command completion feature on single quoted demangled C++
- symbols. Remove when loose ends are cleaned up. FIXME -fnf */
+/* Read-only accessor to AUTO_SELECT_MODE. */
-static void
-cplusplus_hint (char *name)
+const char *
+multiple_symbols_select_mode (void)
{
- while (*name == '\'')
- name++;
- printf_filtered ("Hint: try '%s or '%s\n", name, name);
- printf_filtered ("(Note leading single quote.)\n");
+ return multiple_symbols_mode;
}
+/* Block in which the most recently searched-for symbol was found.
+ Might be better to make this a parameter to lookup_symbol and
+ value_of_this. */
+
+const struct block *block_found;
+
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work. */
@@ -140,9 +159,9 @@ cplusplus_hint (char *name)
struct symtab *
lookup_symtab (const char *name)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
char *real_path = NULL;
char *full_path = NULL;
@@ -166,27 +185,31 @@ got_symtab:
{
return s;
}
-
+
/* 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)
{
- const char *fp = symtab_to_filename (s);
- if (FILENAME_CMP (full_path, fp) == 0)
- {
- return s;
- }
+ const char *fp = symtab_to_fullname (s);
+ if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+ {
+ return s;
+ }
}
if (real_path != NULL)
{
- char *rp = gdb_realpath (symtab_to_filename (s));
- make_cleanup (xfree, rp);
- if (FILENAME_CMP (real_path, rp) == 0)
- {
- return s;
- }
+ char *fullname = symtab_to_fullname (s);
+ if (fullname != NULL)
+ {
+ char *rp = gdb_realpath (fullname);
+ make_cleanup (xfree, rp);
+ if (FILENAME_CMP (real_path, rp) == 0)
+ {
+ return s;
+ }
+ }
}
}
@@ -207,7 +230,7 @@ got_symtab:
return (NULL);
if (ps->readin)
- error ("Internal: readin %s pst for `%s' found when no symtab found.",
+ error (_("Internal: readin %s pst for `%s' found when no symtab found."),
ps->filename, name);
s = PSYMTAB_TO_SYMTAB (ps);
@@ -233,8 +256,8 @@ got_symtab:
struct partial_symtab *
lookup_partial_symtab (const char *name)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct partial_symtab *pst;
+ struct objfile *objfile;
char *full_path = NULL;
char *real_path = NULL;
@@ -259,8 +282,7 @@ lookup_partial_symtab (const char *name)
this symtab and use its absolute path. */
if (full_path != NULL)
{
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL
&& FILENAME_CMP (full_path, pst->fullname) == 0)
{
@@ -271,8 +293,7 @@ lookup_partial_symtab (const char *name)
if (real_path != NULL)
{
char *rp = NULL;
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL)
{
rp = gdb_realpath (pst->fullname);
@@ -334,7 +355,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
is_full_physname_constructor = is_constructor_name (physname);
is_constructor =
- is_full_physname_constructor || (newname && STREQ (field_name, newname));
+ is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0);
if (!is_destructor)
is_destructor = (strncmp (physname, "__dt", 4) == 0);
@@ -384,93 +405,514 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
}
-/* Initialize a symbol's mangled name. */
+/* Initialize the language dependent portion of a symbol
+ depending upon the language for the symbol. */
+void
+symbol_init_language_specific (struct general_symbol_info *gsymbol,
+ enum language language)
+{
+ gsymbol->language = language;
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java
+ || gsymbol->language == language_objc)
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ else
+ {
+ memset (&gsymbol->language_specific, 0,
+ sizeof (gsymbol->language_specific));
+ }
+}
+
+/* Functions to initialize a symbol's mangled name. */
+
+/* Objects of this type are stored in the demangled name hash table. */
+struct demangled_name_entry
+{
+ char *mangled;
+ char demangled[1];
+};
-/* Try to initialize the demangled name for a symbol, based on the
+/* Hash function for the demangled name hash. */
+static hashval_t
+hash_demangled_name_entry (const void *data)
+{
+ const struct demangled_name_entry *e = data;
+ return htab_hash_string (e->mangled);
+}
+
+/* Equality function for the demangled name hash. */
+static int
+eq_demangled_name_entry (const void *a, const void *b)
+{
+ const struct demangled_name_entry *da = a;
+ const struct demangled_name_entry *db = b;
+ return strcmp (da->mangled, db->mangled) == 0;
+}
+
+/* Create the hash table used for demangled names. Each hash entry is
+ a pair of strings; one for the mangled name and one for the demangled
+ name. The entry is hashed via just the mangled name. */
+
+static void
+create_demangled_names_hash (struct objfile *objfile)
+{
+ /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
+ The hash table code will round this up to the next prime number.
+ Choosing a much larger table size wastes memory, and saves only about
+ 1% in symbol reading. */
+
+ objfile->demangled_names_hash = htab_create_alloc
+ (256, hash_demangled_name_entry, eq_demangled_name_entry,
+ NULL, xcalloc, xfree);
+}
+
+/* Try to determine the demangled name for a symbol, based on the
language of that symbol. If the language is set to language_auto,
it will attempt to find any demangling algorithm that works and
- then set the language appropriately. If no demangling of any kind
- is found, the language is set back to language_unknown, so we can
- avoid doing this work again the next time we encounter the symbol.
- Any required space to store the name is obtained from the specified
- obstack. */
+ then set the language appropriately. The returned name is allocated
+ by the demangler and should be xfree'd. */
-void
-symbol_init_demangled_name (struct general_symbol_info *gsymbol,
- struct obstack *obstack)
+static char *
+symbol_find_demangled_name (struct general_symbol_info *gsymbol,
+ const char *mangled)
{
- char *mangled = gsymbol->name;
char *demangled = NULL;
if (gsymbol->language == language_unknown)
gsymbol->language = language_auto;
+
+ if (gsymbol->language == language_objc
+ || gsymbol->language == language_auto)
+ {
+ demangled =
+ objc_demangle (mangled, 0);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_objc;
+ return demangled;
+ }
+ }
if (gsymbol->language == language_cplus
|| gsymbol->language == language_auto)
{
demangled =
- cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI);
+ cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
if (demangled != NULL)
- {
- gsymbol->language = language_cplus;
- gsymbol->language_specific.cplus_specific.demangled_name =
- obsavestring (demangled, strlen (demangled), obstack);
- xfree (demangled);
- }
- else
- {
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
- }
+ {
+ gsymbol->language = language_cplus;
+ return demangled;
+ }
}
if (gsymbol->language == language_java)
{
demangled =
- cplus_demangle (gsymbol->name,
+ cplus_demangle (mangled,
DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
if (demangled != NULL)
- {
- gsymbol->language = language_java;
- gsymbol->language_specific.cplus_specific.demangled_name =
- obsavestring (demangled, strlen (demangled), obstack);
- xfree (demangled);
- }
+ {
+ gsymbol->language = language_java;
+ return demangled;
+ }
+ }
+ return NULL;
+}
+
+/* Set both the mangled and demangled (if any) names for GSYMBOL based
+ on LINKAGE_NAME and LEN. Ordinarily, NAME is copied onto the
+ objfile's obstack; but if COPY_NAME is 0 and if NAME is
+ NUL-terminated, then this function assumes that NAME is already
+ correctly saved (either permanently or with a lifetime tied to the
+ 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,
+ so the pointer can be discarded after calling this function. */
+
+/* We have to be careful when dealing with Java names: when we run
+ into a Java minimal symbol, we don't know it's a Java symbol, so it
+ gets demangled as a C++ name. This is unfortunate, but there's not
+ much we can do about it: but when demangling partial symbols and
+ regular symbols, we'd better not reuse the wrong demangled name.
+ (See PR gdb/1039.) We solve this by putting a distinctive prefix
+ on Java names when storing them in the hash table. */
+
+/* FIXME: carlton/2003-03-13: This is an unfortunate situation. I
+ don't mind the Java prefix so much: different languages have
+ different demangling requirements, so it's only natural that we
+ need to keep language data around in our demangling cache. But
+ it's not good that the minimal symbol has the wrong demangled name.
+ Unfortunately, I can't think of any easy solution to that
+ problem. */
+
+#define JAVA_PREFIX "##JAVA$$"
+#define JAVA_PREFIX_LEN 8
+
+void
+symbol_set_names (struct general_symbol_info *gsymbol,
+ const char *linkage_name, int len, int copy_name,
+ struct objfile *objfile)
+{
+ struct demangled_name_entry **slot;
+ /* A 0-terminated copy of the linkage name. */
+ const char *linkage_name_copy;
+ /* A copy of the linkage name that might have a special Java prefix
+ added to it, for use when looking names up in the hash table. */
+ const char *lookup_name;
+ /* The length of lookup_name. */
+ int lookup_len;
+ struct demangled_name_entry entry;
+
+ if (gsymbol->language == language_ada)
+ {
+ /* In Ada, we do the symbol lookups using the mangled name, so
+ we can save some space by not storing the demangled name.
+
+ As a side note, we have also observed some overlap between
+ the C++ mangling and Ada mangling, similarly to what has
+ been observed with Java. Because we don't store the demangled
+ name with the symbol, we don't need to use the same trick
+ as Java. */
+ if (!copy_name)
+ gsymbol->name = (char *) linkage_name;
else
- {
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
- }
+ {
+ gsymbol->name = obstack_alloc (&objfile->objfile_obstack, len + 1);
+ memcpy (gsymbol->name, linkage_name, len);
+ gsymbol->name[len] = '\0';
+ }
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+
+ return;
}
-#if 0
- /* OBSOLETE if (demangled == NULL */
- /* OBSOLETE && (gsymbol->language == language_chill */
- /* OBSOLETE || gsymbol->language == language_auto)) */
- /* OBSOLETE { */
- /* OBSOLETE demangled = */
- /* OBSOLETE chill_demangle (gsymbol->name); */
- /* OBSOLETE if (demangled != NULL) */
- /* OBSOLETE { */
- /* OBSOLETE gsymbol->language = language_chill; */
- /* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = */
- /* OBSOLETE obsavestring (demangled, strlen (demangled), obstack); */
- /* OBSOLETE xfree (demangled); */
- /* OBSOLETE } */
- /* OBSOLETE else */
- /* OBSOLETE { */
- /* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = NULL; */
- /* OBSOLETE } */
- /* OBSOLETE } */
-#endif
+
+ if (objfile->demangled_names_hash == NULL)
+ create_demangled_names_hash (objfile);
+
+ /* The stabs reader generally provides names that are not
+ NUL-terminated; most of the other readers don't do this, so we
+ can just use the given copy, unless we're in the Java case. */
+ if (gsymbol->language == language_java)
+ {
+ char *alloc_name;
+ lookup_len = len + JAVA_PREFIX_LEN;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN);
+ memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name + JAVA_PREFIX_LEN;
+ }
+ else if (linkage_name[len] != '\0')
+ {
+ char *alloc_name;
+ lookup_len = len;
+
+ alloc_name = alloca (lookup_len + 1);
+ memcpy (alloc_name, linkage_name, len);
+ alloc_name[lookup_len] = '\0';
+
+ lookup_name = alloc_name;
+ linkage_name_copy = alloc_name;
+ }
+ else
+ {
+ lookup_len = len;
+ lookup_name = linkage_name;
+ linkage_name_copy = linkage_name;
+ }
+
+ entry.mangled = (char *) lookup_name;
+ slot = ((struct demangled_name_entry **)
+ htab_find_slot (objfile->demangled_names_hash,
+ &entry, INSERT));
+
+ /* If this name is not in the hash table, add it. */
+ if (*slot == NULL)
+ {
+ char *demangled_name = symbol_find_demangled_name (gsymbol,
+ linkage_name_copy);
+ int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+
+ /* Suppose we have demangled_name==NULL, copy_name==0, and
+ lookup_name==linkage_name. In this case, we already have the
+ mangled name saved, and we don't have a demangled name. So,
+ you might think we could save a little space by not recording
+ this in the hash table at all.
+
+ It turns out that it is actually important to still save such
+ an entry in the hash table, because storing this name gives
+ us better backache hit rates for partial symbols. */
+ if (!copy_name && lookup_name == linkage_name)
+ {
+ *slot = obstack_alloc (&objfile->objfile_obstack,
+ offsetof (struct demangled_name_entry,
+ demangled)
+ + demangled_len + 1);
+ (*slot)->mangled = (char *) lookup_name;
+ }
+ else
+ {
+ /* 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,
+ offsetof (struct demangled_name_entry,
+ demangled)
+ + lookup_len + demangled_len + 2);
+ (*slot)->mangled = &((*slot)->demangled[demangled_len + 1]);
+ strcpy ((*slot)->mangled, lookup_name);
+ }
+
+ if (demangled_name != NULL)
+ {
+ strcpy ((*slot)->demangled, demangled_name);
+ xfree (demangled_name);
+ }
+ else
+ (*slot)->demangled[0] = '\0';
+ }
+
+ gsymbol->name = (*slot)->mangled + lookup_len - len;
+ if ((*slot)->demangled[0] != '\0')
+ gsymbol->language_specific.cplus_specific.demangled_name
+ = (*slot)->demangled;
+ else
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+}
+
+/* Return the source code name of a symbol. In languages where
+ demangling is necessary, this is the demangled name. */
+
+char *
+symbol_natural_name (const struct general_symbol_info *gsymbol)
+{
+ switch (gsymbol->language)
+ {
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
+ }
+ return gsymbol->name;
}
+/* Return the demangled name for a symbol based on the language for
+ that symbol. If no demangled name exists, return NULL. */
+char *
+symbol_demangled_name (const struct general_symbol_info *gsymbol)
+{
+ switch (gsymbol->language)
+ {
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/* Return the search name of a symbol---generally the demangled or
+ linkage name of the symbol, depending on how it will be searched for.
+ If there is no distinct demangled name, then returns the same value
+ (same pointer) as SYMBOL_LINKAGE_NAME. */
+char *
+symbol_search_name (const struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_ada)
+ return gsymbol->name;
+ else
+ return symbol_natural_name (gsymbol);
+}
+/* Initialize the structure fields to zero values. */
+void
+init_sal (struct symtab_and_line *sal)
+{
+ sal->pspace = NULL;
+ sal->symtab = 0;
+ sal->section = 0;
+ sal->line = 0;
+ sal->pc = 0;
+ sal->end = 0;
+ sal->explicit_pc = 0;
+ sal->explicit_line = 0;
+}
+/* Return 1 if the two sections are the same, or if they could
+ plausibly be copies of each other, one in an original object
+ file and another in a separated debug file. */
-/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
+int
+matching_obj_sections (struct obj_section *obj_first,
+ struct obj_section *obj_second)
+{
+ asection *first = obj_first? obj_first->the_bfd_section : NULL;
+ asection *second = obj_second? obj_second->the_bfd_section : NULL;
+ struct objfile *obj;
+
+ /* If they're the same section, then they match. */
+ if (first == second)
+ return 1;
+
+ /* If either is NULL, give up. */
+ if (first == NULL || second == NULL)
+ return 0;
+
+ /* This doesn't apply to absolute symbols. */
+ if (first->owner == NULL || second->owner == NULL)
+ return 0;
+
+ /* If they're in the same object file, they must be different sections. */
+ if (first->owner == second->owner)
+ return 0;
+ /* Check whether the two sections are potentially corresponding. They must
+ have the same size, address, and name. We can't compare section indexes,
+ which would be more reliable, because some sections may have been
+ stripped. */
+ if (bfd_get_section_size (first) != bfd_get_section_size (second))
+ return 0;
+
+ /* In-memory addresses may start at a different offset, relativize them. */
+ if (bfd_get_section_vma (first->owner, first)
+ - bfd_get_start_address (first->owner)
+ != bfd_get_section_vma (second->owner, second)
+ - bfd_get_start_address (second->owner))
+ return 0;
+
+ if (bfd_get_section_name (first->owner, first) == NULL
+ || bfd_get_section_name (second->owner, second) == NULL
+ || strcmp (bfd_get_section_name (first->owner, first),
+ bfd_get_section_name (second->owner, second)) != 0)
+ return 0;
+
+ /* Otherwise check that they are in corresponding objfiles. */
+
+ ALL_OBJFILES (obj)
+ if (obj->obfd == first->owner)
+ break;
+ gdb_assert (obj != NULL);
+
+ if (obj->separate_debug_objfile != NULL
+ && obj->separate_debug_objfile->obfd == second->owner)
+ return 1;
+ if (obj->separate_debug_objfile_backlink != NULL
+ && obj->separate_debug_objfile_backlink->obfd == second->owner)
+ return 1;
+
+ return 0;
+}
+
+/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
+ 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,
+ 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;
+
+ /* An objfile that has its functions reordered might have
+ many partial symbol tables containing the PC, but
+ we want the partial symbol table that contains the
+ function containing the PC. */
+ if (!(objfile->flags & OBJF_REORDERED) &&
+ section == 0) /* can't validate section this way */
+ return pst;
+
+ if (msymbol == NULL)
+ return (pst);
+
+ /* The code range of partial symtabs sometimes overlap, so, in
+ the loop below, we need to check all partial symtabs and
+ find the one that fits better for the given PC address. We
+ select the partial symtab that contains a symbol whose
+ address is closest to the PC address. By closest we mean
+ that find_pc_sect_symbol returns the symbol with address
+ that is closest and still less than the given PC. */
+ for (tpst = pst; tpst != NULL; tpst = tpst->next)
+ {
+ if (pc >= tpst->textlow && pc < tpst->texthigh)
+ {
+ struct partial_symbol *p;
+ CORE_ADDR this_addr;
+
+ /* NOTE: This assumes that every psymbol has a
+ 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);
+ if (p != NULL
+ && SYMBOL_VALUE_ADDRESS (p)
+ == SYMBOL_VALUE_ADDRESS (msymbol))
+ return tpst;
+
+ /* Also accept the textlow value of a psymtab as a
+ "symbol", to provide some support for partial
+ symbol tables with line information but no debug
+ symbols (e.g. those produced by an assembler). */
+ if (p != NULL)
+ this_addr = SYMBOL_VALUE_ADDRESS (p);
+ else
+ this_addr = tpst->textlow;
+
+ /* Check whether it is closer than our current
+ BEST_ADDR. Since this symbol address is
+ necessarily lower or equal to PC, the symbol closer
+ to PC is the symbol which address is the highest.
+ This way we return the psymtab which contains such
+ best match symbol. This can help in cases where the
+ symbol information/debuginfo is not complete, like
+ for instance on IRIX6 with gcc, where no debug info
+ is emitted for statics. (See also the nodebug.exp
+ testcase.) */
+ if (this_addr > best_addr)
+ {
+ best_addr = this_addr;
+ best_pst = tpst;
+ }
+ }
+ }
+ return best_pst;
+}
+
+/* Find which partial symtab contains PC and SECTION. Return 0 if
+ none. We return the psymtab that contains a symbol whose address
+ exactly matches PC, or, if we cannot find an exact match, the
+ psymtab that contains a symbol whose address is closest to PC. */
struct partial_symtab *
-find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
+find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct objfile *objfile;
struct minimal_symbol *msymbol;
/* If we know that this is not a text address, return failure. This is
@@ -478,50 +920,80 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
not include the data ranges. */
msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
if (msymbol
- && (msymbol->type == mst_data
- || msymbol->type == mst_bss
- || msymbol->type == mst_abs
- || msymbol->type == mst_file_data
- || msymbol->type == mst_file_bss))
+ && (MSYMBOL_TYPE (msymbol) == mst_data
+ || MSYMBOL_TYPE (msymbol) == mst_bss
+ || MSYMBOL_TYPE (msymbol) == mst_abs
+ || MSYMBOL_TYPE (msymbol) == mst_file_data
+ || MSYMBOL_TYPE (msymbol) == mst_file_bss))
return NULL;
- ALL_PSYMTABS (objfile, pst)
- {
- if (pc >= pst->textlow && pc < pst->texthigh)
- {
- struct partial_symtab *tpst;
-
- /* An objfile that has its functions reordered might have
- many partial symbol tables containing the PC, but
- we want the partial symbol table that contains the
- function containing the PC. */
- if (!(objfile->flags & OBJF_REORDERED) &&
- section == 0) /* can't validate section this way */
- return (pst);
+ /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
+ than the later used TEXTLOW/TEXTHIGH one. */
- if (msymbol == NULL)
- return (pst);
+ ALL_OBJFILES (objfile)
+ if (objfile->psymtabs_addrmap != NULL)
+ {
+ struct partial_symtab *pst;
- for (tpst = pst; tpst != NULL; tpst = tpst->next)
+ pst = addrmap_find (objfile->psymtabs_addrmap, pc);
+ if (pst != NULL)
{
- if (pc >= tpst->textlow && pc < tpst->texthigh)
+ /* 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)
{
struct partial_symbol *p;
-
- p = find_pc_sect_psymbol (tpst, pc, section);
- if (p != NULL
- && SYMBOL_VALUE_ADDRESS (p)
- == SYMBOL_VALUE_ADDRESS (msymbol))
- return (tpst);
+ /* NOTE: This assumes that every psymbol has a
+ 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);
+ if (!p
+ || SYMBOL_VALUE_ADDRESS (p)
+ != SYMBOL_VALUE_ADDRESS (msymbol))
+ continue;
}
+
+ /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
+ PSYMTABS_ADDRMAP we used has already the best 1-byte
+ granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
+ a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
+ overlap. */
+
+ return pst;
}
- return (pst);
}
- }
- return (NULL);
+
+ /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
+ which still have no corresponding full SYMTABs read. But it is not
+ present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
+ so far. */
+
+ ALL_OBJFILES (objfile)
+ {
+ struct partial_symtab *pst;
+
+ /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
+ its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
+ debug info type in single OBJFILE. */
+
+ ALL_OBJFILE_PSYMTABS (objfile, pst)
+ if (pc >= pst->textlow && pc < pst->texthigh)
+ {
+ struct partial_symtab *best_pst;
+
+ best_pst = find_pc_sect_psymtab_closer (pc, section, pst,
+ msymbol);
+ if (best_pst != NULL)
+ return best_pst;
+ }
+ }
+
+ return NULL;
}
-/* Find which partial symtab contains PC. Return 0 if none.
+/* Find which partial symtab contains PC. Return 0 if none.
Backward compatibility, no section */
struct partial_symtab *
@@ -530,12 +1002,12 @@ find_pc_psymtab (CORE_ADDR pc)
return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
}
-/* Find which partial symbol within a psymtab matches PC and SECTION.
+/* Find which partial symbol within a psymtab matches PC and SECTION.
Return 0 if none. Check all psymtabs if PSYMTAB is 0. */
struct partial_symbol *
find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
- asection *section)
+ struct obj_section *section)
{
struct partial_symbol *best = NULL, *p, **pp;
CORE_ADDR best_pc;
@@ -557,7 +1029,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
pp++)
{
p = *pp;
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc
@@ -567,7 +1039,7 @@ 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 (SYMBOL_BFD_SECTION (p) != section)
+ if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
continue;
}
best_pc = SYMBOL_VALUE_ADDRESS (p);
@@ -581,7 +1053,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
pp++)
{
p = *pp;
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
&& SYMBOL_CLASS (p) == LOC_BLOCK
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& (SYMBOL_VALUE_ADDRESS (p) > best_pc
@@ -591,7 +1063,7 @@ 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 (SYMBOL_BFD_SECTION (p) != section)
+ if (!matching_obj_sections (SYMBOL_OBJ_SECTION (p), section))
continue;
}
best_pc = SYMBOL_VALUE_ADDRESS (p);
@@ -602,7 +1074,7 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
return best;
}
-/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
+/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
Check all psymtabs if PSYMTAB is 0. Backwards compatibility, no section. */
struct partial_symbol *
@@ -615,28 +1087,115 @@ find_pc_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc)
out of the minimal symbols and stash that in the debug symbol. */
static void
-fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
+fixup_section (struct general_symbol_info *ginfo,
+ CORE_ADDR addr, struct objfile *objfile)
{
struct minimal_symbol *msym;
- msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+ /* First, check whether a minimal symbol with the same name exists
+ and points to the same address. The address check is required
+ e.g. on PowerPC64, where the minimal symbol for a function will
+ point to the function descriptor, while the debug symbol will
+ point to the actual function code. */
+ msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
if (msym)
{
- ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+ ginfo->obj_section = SYMBOL_OBJ_SECTION (msym);
ginfo->section = SYMBOL_SECTION (msym);
}
+ else
+ {
+ /* Static, function-local variables do appear in the linker
+ (minimal) symbols, but are frequently given names that won't
+ be found via lookup_minimal_symbol(). E.g., it has been
+ observed in frv-uclinux (ELF) executables that a static,
+ function-local variable named "foo" might appear in the
+ linker symbols as "foo.6" or "foo.3". Thus, there is no
+ point in attempting to extend the lookup-by-name mechanism to
+ handle this case due to the fact that there can be multiple
+ names.
+
+ So, instead, search the section table when lookup by name has
+ failed. The ``addr'' and ``endaddr'' fields may have already
+ been relocated. If so, the relocation offset (i.e. the
+ ANOFFSET value) needs to be subtracted from these values when
+ performing the comparison. We unconditionally subtract it,
+ because, when no relocation has been performed, the ANOFFSET
+ value will simply be zero.
+
+ The address of the symbol whose section we're fixing up HAS
+ NOT BEEN adjusted (relocated) yet. It can't have been since
+ the section isn't yet known and knowing the section is
+ necessary in order to add the correct relocation value. In
+ other words, we wouldn't even be in this function (attempting
+ to compute the section) if it were already known.
+
+ Note that it is possible to search the minimal symbols
+ (subtracting the relocation value if necessary) to find the
+ matching minimal symbol, but this is overkill and much less
+ efficient. It is not necessary to find the matching minimal
+ symbol, only its section.
+
+ Note that this technique (of doing a section table search)
+ can fail when unrelocated section addresses overlap. For
+ this reason, we still attempt a lookup by name prior to doing
+ a search of the section table. */
+
+ struct obj_section *s;
+ ALL_OBJFILE_OSECTIONS (objfile, s)
+ {
+ int idx = s->the_bfd_section->index;
+ CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+
+ if (obj_section_addr (s) - offset <= addr
+ && addr < obj_section_endaddr (s) - offset)
+ {
+ ginfo->obj_section = s;
+ ginfo->section = idx;
+ return;
+ }
+ }
+ }
}
struct symbol *
fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
{
+ CORE_ADDR addr;
+
if (!sym)
return NULL;
- if (SYMBOL_BFD_SECTION (sym))
+ if (SYMBOL_OBJ_SECTION (sym))
return sym;
- fixup_section (&sym->ginfo, objfile);
+ /* 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));
+
+ if (objfile == NULL)
+ objfile = SYMBOL_SYMTAB (sym)->objfile;
+
+ /* We should have an objfile by now. */
+ gdb_assert (objfile);
+
+ switch (SYMBOL_CLASS (sym))
+ {
+ case LOC_STATIC:
+ case LOC_LABEL:
+ addr = SYMBOL_VALUE_ADDRESS (sym);
+ break;
+ case LOC_BLOCK:
+ addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ break;
+
+ default:
+ /* Nothing else will be listed in the minsyms -- no use looking
+ it up. */
+ return sym;
+ }
+
+ fixup_section (&sym->ginfo, addr, objfile);
return sym;
}
@@ -644,25 +1203,40 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
struct partial_symbol *
fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
{
+ CORE_ADDR addr;
+
if (!psym)
return NULL;
- if (SYMBOL_BFD_SECTION (psym))
+ if (SYMBOL_OBJ_SECTION (psym))
return psym;
- fixup_section (&psym->ginfo, objfile);
+ gdb_assert (objfile);
+
+ switch (SYMBOL_CLASS (psym))
+ {
+ case LOC_STATIC:
+ case LOC_LABEL:
+ case LOC_BLOCK:
+ addr = SYMBOL_VALUE_ADDRESS (psym);
+ break;
+ default:
+ /* Nothing else will be listed in the minsyms -- no use looking
+ it up. */
+ return psym;
+ }
+
+ fixup_section (&psym->ginfo, addr, objfile);
return psym;
}
/* Find the definition for a specified symbol name NAME
- in namespace NAMESPACE, visible from lexical block BLOCK.
+ in domain DOMAIN, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
- If SYMTAB is non-NULL, store the symbol table in which the
- symbol was found there, or NULL if not found.
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
NAME is a field of the current implied argument `this'. If so set
- *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+ *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
BLOCK_FOUND is set to the block in which NAME is found (in the case of
a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
@@ -670,35 +1244,57 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
attractive to put in some QUIT's (though I'm not really sure
whether it can run long enough to be really important). But there
are a few calls for which it would appear to be bad news to quit
- out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
- nindy_frame_chain_valid in nindy-tdep.c. (Note that there is C++
- code below which can error(), but that probably doesn't affect
- these calls since they are looking for a known variable and thus
- can probably assume it will never hit the C++ code). */
+ out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
+ that there is C++ code below which can error(), but that probably
+ doesn't affect these calls since they are looking for a known
+ variable and thus can probably assume it will never hit the C++
+ code). */
struct symbol *
-lookup_symbol (const char *name, const struct block *block,
- const namespace_enum namespace, int *is_a_field_of_this,
- struct symtab **symtab)
+lookup_symbol_in_language (const char *name, const struct block *block,
+ const domain_enum domain, enum language lang,
+ int *is_a_field_of_this)
{
char *demangled_name = NULL;
const char *modified_name = NULL;
const char *mangled_name = NULL;
- int needtofreename = 0;
struct symbol *returnval;
+ struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
modified_name = name;
- /* If we are using C++ language, demangle the name before doing a lookup, so
+ /* If we are using C++ or Java, demangle the name before doing a lookup, so
we can always binary search. */
- if (current_language->la_language == language_cplus)
+ if (lang == language_cplus)
{
demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
if (demangled_name)
{
mangled_name = name;
modified_name = demangled_name;
- needtofreename = 1;
+ make_cleanup (xfree, demangled_name);
+ }
+ else
+ {
+ /* If we were given a non-mangled name, canonicalize it
+ according to the language (so far only for C++). */
+ demangled_name = cp_canonicalize_string (name);
+ if (demangled_name)
+ {
+ modified_name = demangled_name;
+ make_cleanup (xfree, demangled_name);
+ }
+ }
+ }
+ else if (lang == language_java)
+ {
+ demangled_name = cplus_demangle (name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ make_cleanup (xfree, demangled_name);
}
}
@@ -716,389 +1312,460 @@ lookup_symbol (const char *name, const struct block *block,
}
returnval = lookup_symbol_aux (modified_name, mangled_name, block,
- namespace, is_a_field_of_this, symtab);
- if (needtofreename)
- xfree (demangled_name);
+ domain, lang, is_a_field_of_this);
+ do_cleanups (cleanup);
- return returnval;
+ return returnval;
}
+/* Behave like lookup_symbol_in_language, but performed with the
+ current language. */
+
+struct symbol *
+lookup_symbol (const char *name, const struct block *block,
+ domain_enum domain, int *is_a_field_of_this)
+{
+ return lookup_symbol_in_language (name, block, domain,
+ current_language->la_language,
+ is_a_field_of_this);
+}
+
+/* Behave like lookup_symbol except that NAME is the natural name
+ of the symbol that we're looking for and, if LINKAGE_NAME is
+ non-NULL, ensure that the symbol's linkage name matches as
+ well. */
+
static struct symbol *
-lookup_symbol_aux (const char *name, const char *mangled_name,
- const struct block *block, const namespace_enum namespace,
- int *is_a_field_of_this, struct symtab **symtab)
+lookup_symbol_aux (const char *name, const char *linkage_name,
+ const struct block *block, const domain_enum domain,
+ enum language language, int *is_a_field_of_this)
{
- register struct symbol *sym;
- register struct symtab *s = NULL;
- register struct partial_symtab *ps;
- register struct blockvector *bv;
- register struct objfile *objfile = NULL;
- register struct block *b;
- register struct minimal_symbol *msymbol;
+ struct symbol *sym;
+ const struct language_defn *langdef;
+
+ /* 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 and expect it to be either 0 or 1.
+ If we don't set it, the contents of is_a_field_of_this are
+ undefined. */
+ if (is_a_field_of_this != NULL)
+ *is_a_field_of_this = 0;
+
+ /* Search specified block and its superiors. Don't search
+ STATIC_BLOCK or GLOBAL_BLOCK. */
+
+ sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+ if (sym != NULL)
+ 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'. */
- /* Search specified block and its superiors. */
+ langdef = language_def (language);
- while (block != 0)
+ if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
+ && block != NULL)
{
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ struct symbol *sym = NULL;
+ /* 'this' is only defined in the function's block, so find the
+ enclosing function block. */
+ for (; block && !BLOCK_FUNCTION (block);
+ block = BLOCK_SUPERBLOCK (block));
+
+ if (block && !dict_empty (BLOCK_DICT (block)))
+ sym = lookup_block_symbol (block, langdef->la_name_of_this,
+ NULL, VAR_DOMAIN);
if (sym)
{
- block_found = block;
- if (symtab != NULL)
+ struct type *t = sym->type;
+
+ /* I'm not really sure that type of this can ever
+ be typedefed; just be safe. */
+ CHECK_TYPEDEF (t);
+ if (TYPE_CODE (t) == TYPE_CODE_PTR
+ || TYPE_CODE (t) == TYPE_CODE_REF)
+ t = TYPE_TARGET_TYPE (t);
+
+ if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+ && TYPE_CODE (t) != TYPE_CODE_UNION)
+ error (_("Internal error: `%s' is not an aggregate"),
+ langdef->la_name_of_this);
+
+ if (check_field (t, name))
{
- /* Search the list of symtabs for one which contains the
- address of the start of this block. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- goto found;
- }
- found:
- *symtab = s;
+ *is_a_field_of_this = 1;
+ return NULL;
}
-
- return fixup_symbol_section (sym, objfile);
}
- block = BLOCK_SUPERBLOCK (block);
}
- /* FIXME: this code is never executed--block is always NULL at this
- point. What is it trying to do, anyway? We already should have
- checked the STATIC_BLOCK above (it is the superblock of top-level
- blocks). Why is VAR_NAMESPACE special-cased? */
- /* Don't need to mess with the psymtabs; if we have a block,
- that file is read in. If we don't, then we deal later with
- all the psymtab stuff that needs checking. */
- /* Note (RT): The following never-executed code looks unnecessary to me also.
- * If we change the code to use the original (passed-in)
- * value of 'block', we could cause it to execute, but then what
- * would it do? The STATIC_BLOCK of the symtab containing the passed-in
- * 'block' was already searched by the above code. And the STATIC_BLOCK's
- * of *other* symtabs (those files not containing 'block' lexically)
- * should not contain 'block' address-wise. So we wouldn't expect this
- * code to find any 'sym''s that were not found above. I vote for
- * deleting the following paragraph of code.
- */
- if (namespace == VAR_NAMESPACE && block != NULL)
- {
- struct block *b;
- /* Find the right symtab. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (block)
- && BLOCK_END (b) > BLOCK_START (block))
- {
- sym = lookup_block_symbol (b, name, mangled_name, VAR_NAMESPACE);
- if (sym)
- {
- block_found = b;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
- }
- }
+ /* Now do whatever is appropriate for LANGUAGE to look
+ up static and global variables. */
+ sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
+ if (sym != NULL)
+ return sym;
- /* C++: If requested to do so by the caller,
- check to see if NAME is a field of `this'. */
- if (is_a_field_of_this)
+ /* Now search all static file-level symbols. Not strictly correct,
+ but more useful than an error. Do the symtabs first, then check
+ the psymtabs. If a psymtab indicates the existence of the
+ desired name as a file-level static, then do psymtab-to-symtab
+ conversion on the fly and return the found symbol. */
+
+ sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
+ if (sym != NULL)
+ return sym;
+
+ sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
+ if (sym != NULL)
+ return sym;
+
+ return NULL;
+}
+
+/* Check to see if the symbol is defined in BLOCK or its superiors.
+ Don't search STATIC_BLOCK or GLOBAL_BLOCK. */
+
+static struct symbol *
+lookup_symbol_aux_local (const char *name, const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *sym;
+ const struct block *static_block = block_static_block (block);
+
+ /* Check if either no block is specified or it's a global block. */
+
+ if (static_block == NULL)
+ return NULL;
+
+ while (block != static_block)
{
- struct value *v = value_of_this (0);
+ sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
+ if (sym != NULL)
+ return sym;
- *is_a_field_of_this = 0;
- if (v && check_field (v, name))
- {
- *is_a_field_of_this = 1;
- if (symtab != NULL)
- *symtab = NULL;
- return NULL;
- }
+ if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
+ break;
+ block = BLOCK_SUPERBLOCK (block);
}
- /* Now search all global blocks. Do the symtab's first, then
- check the psymtab's. If a psymtab indicates the existence
- of the desired name as a global, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+ /* We've reached the edge of the function without finding a result. */
- ALL_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
- if (sym)
+ return NULL;
+}
+
+/* Look up OBJFILE to BLOCK. */
+
+static struct objfile *
+lookup_objfile_from_block (const struct block *block)
+{
+ struct objfile *obj;
+ struct symtab *s;
+
+ if (block == NULL)
+ return NULL;
+
+ block = block_global_block (block);
+ /* Go through SYMTABS. */
+ ALL_SYMTABS (obj, s)
+ if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK))
{
- block_found = block;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
+ if (obj->separate_debug_objfile_backlink)
+ obj = obj->separate_debug_objfile_backlink;
+
+ return obj;
}
- }
-#ifndef HPUXHPPA
+ return NULL;
+}
+
+/* Look up a symbol in a block; if found, fixup the symbol, and set
+ block_found appropriately. */
- /* Check for the possibility of the symbol being a function or
- a mangled variable that is stored in one of the minimal symbol tables.
- Eventually, all global symbols might be resolved in this way. */
+struct symbol *
+lookup_symbol_aux_block (const char *name, const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *sym;
- if (namespace == VAR_NAMESPACE)
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ if (sym)
{
- msymbol = lookup_minimal_symbol (name, NULL, NULL);
- if (msymbol != NULL)
- {
- s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
- SYMBOL_BFD_SECTION (msymbol));
- if (s != NULL)
- {
- /* This is a function which has a symtab for its address. */
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
- /* We kept static functions in minimal symbol table as well as
- in static scope. We want to find them in the symbol table. */
- if (!sym)
- {
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
- }
+ block_found = block;
+ return fixup_symbol_section (sym, NULL);
+ }
- /* sym == 0 if symbol was found in the minimal symbol table
- but not in the symtab.
- Return 0 to use the msymbol definition of "foo_".
+ return NULL;
+}
- This happens for Fortran "foo_" symbols,
- which are "foo" in the symtab.
+/* Check all global symbols in OBJFILE in symtabs and
+ psymtabs. */
- This can also happen if "asm" is used to make a
- regular symbol but not a debugging symbol, e.g.
- asm(".globl _main");
- asm("_main:");
- */
+struct symbol *
+lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
+ const char *name,
+ const char *linkage_name,
+ const domain_enum domain)
+{
+ const struct objfile *objfile;
+ struct symbol *sym;
+ struct blockvector *bv;
+ const struct block *block;
+ struct symtab *s;
+ struct partial_symtab *ps;
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- else if (MSYMBOL_TYPE (msymbol) != mst_text
- && MSYMBOL_TYPE (msymbol) != mst_file_text
- && !STREQ (name, SYMBOL_NAME (msymbol)))
- {
- /* This is a mangled variable, look it up by its
- mangled name. */
- return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name, block,
- namespace, is_a_field_of_this, symtab);
- }
- /* There are no debug symbols for this file, or we are looking
- for an unmangled variable.
- Try to find a matching static symbol below. */
- }
+ for (objfile = main_objfile;
+ objfile;
+ objfile = objfile_separate_debug_iterate (main_objfile, objfile))
+ {
+ /* Go through symtabs. */
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ if (sym)
+ {
+ block_found = block;
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
+
+ /* Now go through psymtabs. */
+ ALL_OBJFILE_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin
+ && lookup_partial_symbol (ps, name, linkage_name,
+ 1, domain))
+ {
+ s = PSYMTAB_TO_SYMTAB (ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
+ return fixup_symbol_section (sym, (struct objfile *)objfile);
+ }
+ }
}
-#endif
+ return NULL;
+}
- ALL_PSYMTABS (objfile, ps)
- {
- if (!ps->readin && lookup_partial_symbol (ps, name, 1, namespace))
- {
- s = PSYMTAB_TO_SYMTAB (ps);
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
- if (!sym)
- {
- /* This shouldn't be necessary, but as a last resort
- * try looking in the statics even though the psymtab
- * claimed the symbol was global. It's possible that
- * the psymtab gets it wrong in some cases.
- */
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
- if (!sym)
- error ("Internal: global 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).",
- name, ps->filename, name, name);
- }
- if (symtab != NULL)
- *symtab = s;
- return fixup_symbol_section (sym, objfile);
- }
- }
+/* Check to see if the symbol is defined in one of the symtabs.
+ BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
+ depending on whether or not we want to search global symbols or
+ static symbols. */
- /* Now search all static file-level symbols.
- Not strictly correct, but more useful than an error.
- Do the symtabs first, then check the psymtabs.
- If a psymtab indicates the existence
- of the desired name as a file-level static, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+static struct symbol *
+lookup_symbol_aux_symtabs (int block_index,
+ const char *name, const char *linkage_name,
+ const domain_enum domain)
+{
+ struct symbol *sym;
+ struct objfile *objfile;
+ struct blockvector *bv;
+ const struct block *block;
+ struct symtab *s;
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (sym)
{
block_found = block;
- if (symtab != NULL)
- *symtab = s;
return fixup_symbol_section (sym, objfile);
}
}
+ return NULL;
+}
+
+/* Check to see if the symbol is defined in one of the partial
+ symtabs. BLOCK_INDEX should be either GLOBAL_BLOCK or
+ STATIC_BLOCK, depending on whether or not we want to search global
+ symbols or static symbols. */
+
+static struct symbol *
+lookup_symbol_aux_psymtabs (int block_index, const char *name,
+ const char *linkage_name,
+ const domain_enum domain)
+{
+ struct symbol *sym;
+ struct objfile *objfile;
+ struct blockvector *bv;
+ const struct block *block;
+ struct partial_symtab *ps;
+ struct symtab *s;
+ const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
+
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 0, namespace))
+ if (!ps->readin
+ && lookup_partial_symbol (ps, name, linkage_name,
+ psymtab_index, domain))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
{
- /* This shouldn't be necessary, but as a last resort
- * try looking in the globals even though the psymtab
- * claimed the symbol was static. It's possible that
- * the psymtab gets it wrong in some cases.
- */
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, mangled_name, namespace);
+ /* This shouldn't be necessary, but as a last resort try
+ looking in the statics even though the psymtab claimed
+ the symbol was global, or vice-versa. It's possible
+ that the psymtab gets it wrong in some cases. */
+
+ /* FIXME: carlton/2002-09-30: Should we really do that?
+ If that happens, isn't it likely to be a GDB error, in
+ which case we should fix the GDB error rather than
+ silently dealing with it here? So I'd vote for
+ removing the check for the symbol in the other
+ block. */
+ block = BLOCKVECTOR_BLOCK (bv,
+ block_index == GLOBAL_BLOCK ?
+ STATIC_BLOCK : GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
- error ("Internal: static 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).",
+ 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)."),
+ block_index == GLOBAL_BLOCK ? "global" : "static",
name, ps->filename, name, name);
}
- if (symtab != NULL)
- *symtab = s;
return fixup_symbol_section (sym, objfile);
}
}
-#ifdef HPUXHPPA
-
- /* Check for the possibility of the symbol being a function or
- a global variable that is stored in one of the minimal symbol tables.
- The "minimal symbol table" is built from linker-supplied info.
-
- RT: I moved this check to last, after the complete search of
- the global (p)symtab's and static (p)symtab's. For HP-generated
- symbol tables, this check was causing a premature exit from
- lookup_symbol with NULL return, and thus messing up symbol lookups
- of things like "c::f". It seems to me a check of the minimal
- symbol table ought to be a last resort in any case. I'm vaguely
- worried about the comment below which talks about FORTRAN routines "foo_"
- though... is it saying we need to do the "minsym" check before
- the static check in this case?
- */
+ return NULL;
+}
- if (namespace == VAR_NAMESPACE)
- {
- msymbol = lookup_minimal_symbol (name, NULL, NULL);
- if (msymbol != NULL)
- {
- /* OK, we found a minimal symbol in spite of not
- * finding any symbol. There are various possible
- * explanations for this. One possibility is the symbol
- * exists in code not compiled -g. Another possibility
- * is that the 'psymtab' isn't doing its job.
- * A third possibility, related to #2, is that we were confused
- * by name-mangling. For instance, maybe the psymtab isn't
- * doing its job because it only know about demangled
- * names, but we were given a mangled name...
- */
-
- /* We first use the address in the msymbol to try to
- * locate the appropriate symtab. Note that find_pc_symtab()
- * has a side-effect of doing psymtab-to-symtab expansion,
- * for the found symtab.
- */
- s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
- if (s != NULL)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
- /* We kept static functions in minimal symbol table as well as
- in static scope. We want to find them in the symbol table. */
- if (!sym)
- {
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
- }
- /* If we found one, return it */
- if (sym)
- {
- if (symtab != NULL)
- *symtab = s;
- return sym;
- }
+/* A default version of lookup_symbol_nonlocal for use by languages
+ that can't think of anything better to do. This implements the C
+ lookup rules. */
- /* If we get here with sym == 0, the symbol was
- found in the minimal symbol table
- but not in the symtab.
- Fall through and return 0 to use the msymbol
- definition of "foo_".
- (Note that outer code generally follows up a call
- to this routine with a call to lookup_minimal_symbol(),
- so a 0 return means we'll just flow into that other routine).
-
- This happens for Fortran "foo_" symbols,
- which are "foo" in the symtab.
-
- This can also happen if "asm" is used to make a
- regular symbol but not a debugging symbol, e.g.
- asm(".globl _main");
- asm("_main:");
- */
- }
+struct symbol *
+basic_lookup_symbol_nonlocal (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *sym;
+
+ /* NOTE: carlton/2003-05-19: The comments below were written when
+ this (or what turned into this) was part of lookup_symbol_aux;
+ I'm much less worried about these questions now, since these
+ decisions have turned out well, but I leave these comments here
+ for posterity. */
+
+ /* NOTE: carlton/2002-12-05: There is a question as to whether or
+ not it would be appropriate to search the current global block
+ here as well. (That's what this code used to do before the
+ is_a_field_of_this check was moved up.) On the one hand, it's
+ redundant with the lookup_symbol_aux_symtabs search that happens
+ next. On the other hand, if decode_line_1 is passed an argument
+ like filename:var, then the user presumably wants 'var' to be
+ searched for in filename. On the third hand, there shouldn't be
+ multiple global variables all of which are named 'var', and it's
+ not like decode_line_1 has ever restricted its search to only
+ global variables in a single filename. All in all, only
+ searching the static block here seems best: it's correct and it's
+ cleanest. */
+
+ /* NOTE: carlton/2002-12-05: There's also a possible performance
+ issue here: if you usually search for global symbols in the
+ current file, then it would be slightly better to search the
+ current global block before searching all the symtabs. But there
+ are other factors that have a much greater effect on performance
+ than that one, so I don't think we should worry about that for
+ now. */
+
+ sym = lookup_symbol_static (name, linkage_name, block, domain);
+ if (sym != NULL)
+ return sym;
- /* If the lookup-by-address fails, try repeating the
- * entire lookup process with the symbol name from
- * the msymbol (if different from the original symbol name).
- */
- else if (MSYMBOL_TYPE (msymbol) != mst_text
- && MSYMBOL_TYPE (msymbol) != mst_file_text
- && !STREQ (name, SYMBOL_NAME (msymbol)))
- {
- return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
- block, namespace, is_a_field_of_this,
- symtab);
- }
- }
- }
+ return lookup_symbol_global (name, linkage_name, block, domain);
+}
+
+/* Lookup a symbol in the static block associated to BLOCK, if there
+ is one; do nothing if BLOCK is NULL or a global block. */
+
+struct symbol *
+lookup_symbol_static (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ const struct block *static_block = block_static_block (block);
+
+ if (static_block != NULL)
+ return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
+ else
+ return NULL;
+}
+
+/* Lookup a symbol in all files' global blocks (searching psymtabs if
+ necessary). */
+
+struct symbol *
+lookup_symbol_global (const char *name,
+ const char *linkage_name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *sym = NULL;
+ struct objfile *objfile = NULL;
+
+ /* Call library-specific lookup procedure. */
+ objfile = lookup_objfile_from_block (block);
+ if (objfile != NULL)
+ sym = solib_global_lookup (objfile, name, linkage_name, domain);
+ if (sym != NULL)
+ return sym;
-#endif
+ sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+ if (sym != NULL)
+ return sym;
- if (symtab != NULL)
- *symtab = NULL;
- return 0;
+ return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+}
+
+int
+symbol_matches_domain (enum language symbol_language,
+ domain_enum symbol_domain,
+ domain_enum domain)
+{
+ /* For C++ "struct foo { ... }" also defines a typedef for "foo".
+ A Java class declaration also defines a typedef for the class.
+ Similarly, any Ada type declaration implicitly defines a typedef. */
+ if (symbol_language == language_cplus
+ || symbol_language == language_java
+ || symbol_language == language_ada)
+ {
+ if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
+ && symbol_domain == STRUCT_DOMAIN)
+ return 1;
+ }
+ /* For all other languages, strict match is required. */
+ return (symbol_domain == domain);
}
-
-/* Look, in partial_symtab PST, for symbol 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, int global,
- namespace_enum namespace)
+/* Look, in partial_symtab PST, for symbol whose natural name is NAME.
+ If LINKAGE_NAME is non-NULL, check in addition that the symbol's
+ linkage name matches it. Check the global symbols if GLOBAL, the
+ static symbols if not */
+
+struct partial_symbol *
+lookup_partial_symbol (struct partial_symtab *pst, const char *name,
+ const char *linkage_name, int global,
+ domain_enum domain)
{
struct partial_symbol *temp;
struct partial_symbol **start, **psym;
- struct partial_symbol **top, **bottom, **center;
+ struct partial_symbol **top, **real_top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
-
+
if (length == 0)
{
return (NULL);
@@ -1106,29 +1773,31 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
-
+
if (global) /* This means we can use a binary search. */
{
do_linear_search = 0;
/* Binary search. This search is guaranteed to end with center
- pointing at the earliest partial symbol with the correct
- name. At that point *all* partial symbols with that name
- will be checked against the correct namespace. */
+ pointing at the earliest partial symbol whose name might be
+ correct. At that point *all* partial symbols with an
+ appropriate name will be checked against the correct
+ domain. */
bottom = start;
top = start + length - 1;
+ real_top = top;
while (top > bottom)
{
center = bottom + (top - bottom) / 2;
if (!(center < top))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
if (!do_linear_search
&& (SYMBOL_LANGUAGE (*center) == language_java))
{
do_linear_search = 1;
}
- if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
{
top = center;
}
@@ -1138,17 +1807,16 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
}
}
if (!(top == bottom))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
- /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
- we don't have to force a linear search on C++. Probably holds true
- for JAVA as well, no way to check.*/
- while (SYMBOL_MATCHES_NAME (*top,name))
+ while (top <= real_top
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
+ : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
{
- if (SYMBOL_NAMESPACE (*top) == namespace)
- {
- return (*top);
- }
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+ SYMBOL_DOMAIN (*top), domain))
+ return (*top);
top++;
}
}
@@ -1157,12 +1825,15 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
we should also do a linear search. */
if (do_linear_search)
- {
+ {
for (psym = start; psym < start + length; psym++)
{
- if (namespace == SYMBOL_NAMESPACE (*psym))
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+ SYMBOL_DOMAIN (*psym), domain))
{
- if (SYMBOL_MATCHES_NAME (*psym, name))
+ if (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
+ : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
{
return (*psym);
}
@@ -1173,34 +1844,42 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
return (NULL);
}
-/* Look up a type named NAME in the struct_namespace. The type returned
- must not be opaque -- i.e., must have at least one field defined
+/* Look up a type named NAME in the struct_domain. The type returned
+ must not be opaque -- i.e., must have at least one field
+ defined. */
- This code was modelled on lookup_symbol -- the parts not relevant to looking
- up types were just left out. In particular it's assumed here that types
- are available in struct_namespace and only at file-static or global blocks. */
+struct type *
+lookup_transparent_type (const char *name)
+{
+ return current_language->la_lookup_transparent_type (name);
+}
+/* The standard implementation of lookup_transparent_type. This code
+ was modeled on lookup_symbol -- the parts not relevant to looking
+ up types were just left out. In particular it's assumed here that
+ types are available in struct_domain and only at file-static or
+ global blocks. */
struct type *
-lookup_transparent_type (const char *name)
+basic_lookup_transparent_type (const char *name)
{
- register struct symbol *sym;
- register struct symtab *s = NULL;
- register struct partial_symtab *ps;
+ struct symbol *sym;
+ struct symtab *s = NULL;
+ struct partial_symtab *ps;
struct blockvector *bv;
- register struct objfile *objfile;
- register struct block *block;
+ struct objfile *objfile;
+ struct block *block;
/* Now search all the global symbols. Do the symtab's first, then
check the psymtab's. If a psymtab indicates the existence
of the desired name as a global, then do psymtab-to-symtab
conversion on the fly and return the found symbol. */
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
{
return SYMBOL_TYPE (sym);
@@ -1209,12 +1888,13 @@ lookup_transparent_type (const char *name)
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+ if (!ps->readin && lookup_partial_symbol (ps, name, NULL,
+ 1, STRUCT_DOMAIN))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
{
/* This shouldn't be necessary, but as a last resort
@@ -1223,11 +1903,11 @@ lookup_transparent_type (const char *name)
* the psymtab gets it wrong in some cases.
*/
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: global 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).",
+(if a template, try specifying an instantiation: %s)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -1243,11 +1923,11 @@ lookup_transparent_type (const char *name)
conversion on the fly and return the found symbol.
*/
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
{
return SYMBOL_TYPE (sym);
@@ -1256,12 +1936,12 @@ lookup_transparent_type (const char *name)
ALL_PSYMTABS (objfile, ps)
{
- if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+ if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN))
{
s = PSYMTAB_TO_SYMTAB (ps);
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
{
/* This shouldn't be necessary, but as a last resort
@@ -1270,11 +1950,11 @@ lookup_transparent_type (const char *name)
* the psymtab gets it wrong in some cases.
*/
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, NULL, STRUCT_NAMESPACE);
+ sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: static 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).",
+(if a template, try specifying an instantiation: %s)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -1292,12 +1972,12 @@ lookup_transparent_type (const char *name)
struct partial_symtab *
find_main_psymtab (void)
{
- register struct partial_symtab *pst;
- register struct objfile *objfile;
+ struct partial_symtab *pst;
+ struct objfile *objfile;
ALL_PSYMTABS (objfile, pst)
{
- if (lookup_partial_symbol (pst, main_name (), 1, VAR_NAMESPACE))
+ if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
{
return (pst);
}
@@ -1305,247 +1985,91 @@ find_main_psymtab (void)
return (NULL);
}
-/* Search BLOCK for symbol NAME in NAMESPACE.
+/* Search BLOCK for symbol NAME in DOMAIN.
Note that if NAME is the demangled form of a C++ symbol, we will fail
to find a match during the binary search of the non-encoded names, but
for now we don't worry about the slight inefficiency of looking for
a match we'll never find, since it will go pretty quick. Once the
binary search terminates, we drop through and do a straight linear
- search on the symbols. Each symbol which is marked as being a C++
- symbol (language_cplus set) has both the encoded and non-encoded names
- tested for a match.
+ search on the symbols. Each symbol which is marked as being a ObjC/C++
+ symbol (language_cplus or language_objc set) has both the encoded and
+ non-encoded names tested for a match.
- If MANGLED_NAME is non-NULL, verify that any symbol we find has this
+ If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
particular mangled name.
*/
struct symbol *
-lookup_block_symbol (register const struct block *block, const char *name,
- const char *mangled_name,
- const namespace_enum namespace)
+lookup_block_symbol (const struct block *block, const char *name,
+ const char *linkage_name,
+ const domain_enum domain)
{
- register int bot, top, inc;
- register struct symbol *sym;
- register struct symbol *sym_found = NULL;
- register int do_linear_search = 1;
+ struct dict_iterator iter;
+ struct symbol *sym;
- if (BLOCK_HASHTABLE (block))
+ if (!BLOCK_FUNCTION (block))
{
- unsigned int hash_index;
- hash_index = msymbol_hash_iw (name);
- hash_index = hash_index % BLOCK_BUCKETS (block);
- for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
+ for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
+ sym != NULL;
+ sym = dict_iter_name_next (name, &iter))
{
- if (SYMBOL_NAMESPACE (sym) == namespace
- && (mangled_name
- ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
- : SYMBOL_MATCHES_NAME (sym, name)))
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain)
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
return sym;
}
return NULL;
}
-
- /* If the blocks's symbols were sorted, start with a binary search. */
-
- if (BLOCK_SHOULD_SORT (block))
+ else
{
- /* Reset the linear search flag so if the binary search fails, we
- won't do the linear search once unless we find some reason to
- do so */
-
- do_linear_search = 0;
- top = BLOCK_NSYMS (block);
- bot = 0;
-
- /* Advance BOT to not far before the first symbol whose name is NAME. */
-
- while (1)
- {
- inc = (top - bot + 1);
- /* No need to keep binary searching for the last few bits worth. */
- if (inc < 4)
- {
- break;
- }
- inc = (inc >> 1) + bot;
- sym = BLOCK_SYM (block, inc);
- if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
- {
- do_linear_search = 1;
- }
- if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
- {
- bot = inc;
- }
- else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
- {
- top = inc;
- }
- else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0)
- {
- bot = inc;
- }
- else
- {
- top = inc;
- }
- }
-
- /* Now scan forward until we run out of symbols, find one whose
- name is greater than NAME, or find one we want. If there is
- more than one symbol with the right name and namespace, we
- return the first one; I believe it is now impossible for us
- to encounter two symbols with the same name and namespace
- here, because blocks containing argument symbols are no
- longer sorted. The exception is for C++, where multiple functions
- (cloned constructors / destructors, in particular) can have
- the same demangled name. So if we have a particular
- mangled name to match, try to do so. */
-
- top = BLOCK_NSYMS (block);
- while (bot < top)
- {
- sym = BLOCK_SYM (block, bot);
- if (SYMBOL_NAMESPACE (sym) == namespace
- && (mangled_name
- ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
- : SYMBOL_MATCHES_NAME (sym, name)))
- {
- return sym;
- }
- if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
- {
- break;
- }
- bot++;
- }
- }
-
- /* Here if block isn't sorted, or we fail to find a match during the
- binary search above. If during the binary search above, we find a
- symbol which is a Java symbol, then we have re-enabled the linear
- search flag which was reset when starting the binary search.
-
- This loop is equivalent to the loop above, but hacked greatly for speed.
+ /* Note that parameter symbols do not always show up last in the
+ list; this loop makes sure to take anything else other than
+ parameter symbols first; it only uses parameter symbols as a
+ last resort. Note that this only takes up extra computation
+ time on a match. */
- Note that parameter symbols do not always show up last in the
- list; this loop makes sure to take anything else other than
- parameter symbols first; it only uses parameter symbols as a
- last resort. Note that this only takes up extra computation
- time on a match. */
+ struct symbol *sym_found = NULL;
- if (do_linear_search)
- {
- top = BLOCK_NSYMS (block);
- bot = 0;
- while (bot < top)
+ for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
+ sym != NULL;
+ sym = dict_iter_name_next (name, &iter))
{
- sym = BLOCK_SYM (block, bot);
- if (SYMBOL_NAMESPACE (sym) == namespace
- && (mangled_name
- ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
- : SYMBOL_MATCHES_NAME (sym, name)))
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain)
+ && (linkage_name != NULL
+ ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
{
- /* If SYM has aliases, then use any alias that is active
- at the current PC. If no alias is active at the current
- PC, then use the main symbol.
-
- ?!? Is checking the current pc correct? Is this routine
- ever called to look up a symbol from another context?
-
- FIXME: No, it's not correct. If someone sets a
- conditional breakpoint at an address, then the
- breakpoint's `struct expression' should refer to the
- `struct symbol' appropriate for the breakpoint's
- address, which may not be the PC.
-
- Even if it were never called from another context,
- it's totally bizarre for lookup_symbol's behavior to
- depend on the value of the inferior's current PC. We
- should pass in the appropriate PC as well as the
- block. The interface to lookup_symbol should change
- to require the caller to provide a PC. */
-
- if (SYMBOL_ALIASES (sym))
- sym = find_active_alias (sym, read_pc ());
-
sym_found = sym;
- if (SYMBOL_CLASS (sym) != LOC_ARG &&
- SYMBOL_CLASS (sym) != LOC_LOCAL_ARG &&
- SYMBOL_CLASS (sym) != LOC_REF_ARG &&
- SYMBOL_CLASS (sym) != LOC_REGPARM &&
- SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
- SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+ if (!SYMBOL_IS_ARGUMENT (sym))
{
break;
}
}
- bot++;
- }
- }
- return (sym_found); /* Will be NULL if not found. */
-}
-
-/* Given a main symbol SYM and ADDR, search through the alias
- list to determine if an alias is active at ADDR and return
- the active alias.
-
- If no alias is active, then return SYM. */
-
-static struct symbol *
-find_active_alias (struct symbol *sym, CORE_ADDR addr)
-{
- struct range_list *r;
- struct alias_list *aliases;
-
- /* If we have aliases, check them first. */
- aliases = SYMBOL_ALIASES (sym);
-
- while (aliases)
- {
- if (!SYMBOL_RANGES (aliases->sym))
- return aliases->sym;
- for (r = SYMBOL_RANGES (aliases->sym); r; r = r->next)
- {
- if (r->start <= addr && r->end > addr)
- return aliases->sym;
}
- aliases = aliases->next;
+ return (sym_found); /* Will be NULL if not found. */
}
-
- /* Nothing found, return the main symbol. */
- return sym;
-}
-
-
-/* Return the symbol for the function which contains a specified
- lexical block, described by a struct block BL. */
-
-struct symbol *
-block_function (struct block *bl)
-{
- while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
- bl = BLOCK_SUPERBLOCK (bl);
-
- return BLOCK_FUNCTION (bl);
}
/* Find the symtab associated with PC and SECTION. Look through the
psymtabs and read in another symtab if necessary. */
struct symtab *
-find_pc_sect_symtab (CORE_ADDR pc, asection *section)
+find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
{
- register struct block *b;
+ struct block *b;
struct blockvector *bv;
- register struct symtab *s = NULL;
- register struct symtab *best_s = NULL;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s = NULL;
+ struct symtab *best_s = NULL;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
+ struct program_space *pspace;
CORE_ADDR distance = 0;
struct minimal_symbol *msymbol;
+ pspace = current_program_space;
+
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on the block's high and low code
addresses, which do not include the data ranges, and because
@@ -1553,11 +2077,11 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
on the partial_symtab's texthigh and textlow. */
msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
if (msymbol
- && (msymbol->type == mst_data
- || msymbol->type == mst_bss
- || msymbol->type == mst_abs
- || msymbol->type == mst_file_data
- || msymbol->type == mst_file_bss))
+ && (MSYMBOL_TYPE (msymbol) == mst_data
+ || MSYMBOL_TYPE (msymbol) == mst_bss
+ || MSYMBOL_TYPE (msymbol) == mst_abs
+ || MSYMBOL_TYPE (msymbol) == mst_file_data
+ || MSYMBOL_TYPE (msymbol) == mst_file_bss))
return NULL;
/* Search all symtabs for the one whose file contains our address, and which
@@ -1575,7 +2099,7 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
It also happens for objfiles that have their functions reordered.
For these, the symtab we are looking for is not necessarily read in. */
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
@@ -1599,16 +2123,16 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
}
if (section != 0)
{
- int i;
+ struct dict_iterator iter;
struct symbol *sym = NULL;
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
fixup_symbol_section (sym, objfile);
- if (section == SYMBOL_BFD_SECTION (sym))
+ if (matching_obj_sections (SYMBOL_OBJ_SECTION (sym), section))
break;
}
- if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
+ if (sym == NULL)
continue; /* no symbol in this symtab matches section */
}
distance = BLOCK_END (b) - BLOCK_START (b);
@@ -1627,9 +2151,9 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
/* Might want to error() here (in case symtab is corrupt and
will cause a core dump), but maybe we can successfully
continue, so let's not. */
- warning ("\
-(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
- paddr_nz (pc));
+ warning (_("\
+(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
+ paddress (get_objfile_arch (ps->objfile), pc));
s = PSYMTAB_TO_SYMTAB (ps);
}
return (s);
@@ -1645,94 +2169,6 @@ find_pc_symtab (CORE_ADDR pc)
}
-#if 0
-
-/* Find the closest symbol value (of any sort -- function or variable)
- for a given address value. Slow but complete. (currently unused,
- mainly because it is too slow. We could fix it if each symtab and
- psymtab had contained in it the addresses ranges of each of its
- sections, which also would be required to make things like "info
- line *0x2345" cause psymtabs to be converted to symtabs). */
-
-struct symbol *
-find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
-{
- struct symtab *symtab, *best_symtab;
- struct objfile *objfile;
- register int bot, top;
- register struct symbol *sym;
- register CORE_ADDR sym_addr;
- struct block *block;
- int blocknum;
-
- /* Info on best symbol seen so far */
-
- register CORE_ADDR best_sym_addr = 0;
- struct symbol *best_sym = 0;
-
- /* FIXME -- we should pull in all the psymtabs, too! */
- ALL_SYMTABS (objfile, symtab)
- {
- /* Search the global and static blocks in this symtab for
- the closest symbol-address to the desired address. */
-
- for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
- {
- QUIT;
- block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
- ALL_BLOCK_SYMBOLS (block, bot, sym)
- {
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_STATIC:
- case LOC_LABEL:
- sym_addr = SYMBOL_VALUE_ADDRESS (sym);
- break;
-
- case LOC_INDIRECT:
- sym_addr = SYMBOL_VALUE_ADDRESS (sym);
- /* An indirect symbol really lives at *sym_addr,
- * so an indirection needs to be done.
- * However, I am leaving this commented out because it's
- * expensive, and it's possible that symbolization
- * could be done without an active process (in
- * case this read_memory will fail). RT
- sym_addr = read_memory_unsigned_integer
- (sym_addr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
- */
- break;
-
- case LOC_BLOCK:
- sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- break;
-
- default:
- continue;
- }
-
- if (sym_addr <= addr)
- if (sym_addr > best_sym_addr)
- {
- /* Quit if we found an exact match. */
- best_sym = sym;
- best_sym_addr = sym_addr;
- best_symtab = symtab;
- if (sym_addr == addr)
- goto done;
- }
- }
- }
- }
-
-done:
- if (symtabp)
- *symtabp = best_symtab;
- if (symaddrp)
- *symaddrp = best_sym_addr;
- return best_sym;
-}
-#endif /* 0 */
-
/* Find the source file and line number for a given PC value and SECTION.
Return a structure containing a symtab pointer, a line number,
and a pc range for the entire source line.
@@ -1751,13 +2187,13 @@ done:
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
-find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
+find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
{
struct symtab *s;
- register struct linetable *l;
- register int len;
- register int i;
- register struct linetable_entry *item;
+ struct linetable *l;
+ int len;
+ int i;
+ struct linetable_entry *item;
struct symtab_and_line val;
struct blockvector *bv;
struct minimal_symbol *msymbol;
@@ -1787,7 +2223,9 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
But what we want is the statement containing the instruction.
Fudge the pc to make sure we get that. */
- INIT_SAL (&val); /* initialize to zeroes */
+ init_sal (&val); /* initialize to zeroes */
+
+ val.pspace = current_program_space;
/* It's tempting to assume that, if we can't find debugging info for
any function enclosing PC, that we shouldn't search for line
@@ -1802,8 +2240,8 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
/* elz: added this because this function returned the wrong
information if the pc belongs to a stub (import/export)
to call a shlib function. This stub would be anywhere between
- two functions in the target, and the line info was erroneously
- taken to be the one of the line before the pc.
+ two functions in the target, and the line info was erroneously
+ taken to be the one of the line before the pc.
*/
/* RT: Further explanation:
@@ -1816,7 +2254,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
* sorted by start address. The stubs are marked as "trampoline",
* the others appear as text. E.g.:
*
- * Minimal symbol table for main image
+ * Minimal symbol table for main image
* main: code for main (text symbol)
* shr1: stub (trampoline symbol)
* foo: code for foo (text symbol)
@@ -1834,7 +2272,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
* Assumptions being made about the minimal symbol table:
* 1. lookup_minimal_symbol_by_pc() will return a trampoline only
* if we're really in the trampoline. If we're beyond it (say
- * we're in "foo" in the above example), it'll have a closer
+ * we're in "foo" in the above example), it'll have a closer
* symbol (the "foo" text symbol for example) and will not
* return the trampoline.
* 2. lookup_minimal_symbol_text() will find a real text symbol
@@ -1847,26 +2285,27 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
if (msymbol != NULL)
if (MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
{
- mfunsym = lookup_minimal_symbol_text (SYMBOL_NAME (msymbol), NULL, NULL);
+ mfunsym = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol),
+ NULL);
if (mfunsym == NULL)
/* I eliminated this warning since it is coming out
* in the following situation:
* gdb shmain // test program with shared libraries
* (gdb) break shr1 // function in shared lib
* Warning: In stub for ...
- * In the above situation, the shared lib is not loaded yet,
+ * In the above situation, the shared lib is not loaded yet,
* so of course we can't find the real func/line info,
* but the "break" still works, and the warning is annoying.
* So I commented out the warning. RT */
- /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
- else if (SYMBOL_VALUE (mfunsym) == SYMBOL_VALUE (msymbol))
+ else if (SYMBOL_VALUE_ADDRESS (mfunsym) == SYMBOL_VALUE_ADDRESS (msymbol))
/* Avoid infinite recursion */
/* See above comment about why warning is commented out */
- /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_NAME(msymbol)) */ ;
+ /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ;
/* fall through */
else
- return find_pc_line (SYMBOL_VALUE (mfunsym), 0);
+ return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
}
@@ -1929,9 +2368,11 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
the first line, prev will not be set. */
/* Is this file's best line closer than the best in the other files?
- If so, record this file, and its best line, as best so far. */
+ If so, record this file, and its best line, as best so far. Don't
+ save prev if it represents the end of a function (i.e. line number
+ 0) instead of a real line. */
- if (prev && (!best || prev->pc > best->pc))
+ if (prev && prev->line && (!best || prev->pc > best->pc))
{
best = prev;
best_symtab = s;
@@ -1951,23 +2392,11 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
if (!best_symtab)
{
- if (!alt_symtab)
- { /* If we didn't find any line # info, just
- return zeros. */
- val.pc = pc;
- }
- else
- {
- val.symtab = alt_symtab;
- val.line = alt->line - 1;
-
- /* Don't return line 0, that means that we didn't find the line. */
- if (val.line == 0)
- ++val.line;
-
- val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
- val.end = alt->pc;
- }
+ /* If we didn't find any line number info, just return zeros.
+ We used to return alt->line - 1 here, but that could be
+ anywhere; if we don't have line number info for this PC,
+ don't make some up. */
+ val.pc = pc;
}
else if (best->line == 0)
{
@@ -1997,7 +2426,7 @@ find_pc_sect_line (CORE_ADDR pc, struct sec *section, int notcurrent)
struct symtab_and_line
find_pc_line (CORE_ADDR pc, int notcurrent)
{
- asection *section;
+ struct obj_section *section;
section = find_pc_overlay (pc);
if (pc_in_unmapped_range (pc, section))
@@ -2018,7 +2447,7 @@ find_pc_line (CORE_ADDR pc, int notcurrent)
struct symtab *
find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
{
- int exact;
+ int exact = 0; /* Initialized here to avoid a compiler warning. */
/* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
so far seen. */
@@ -2047,19 +2476,34 @@ find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
struct objfile *objfile;
struct symtab *s;
+ struct partial_symtab *p;
if (best_index >= 0)
best = best_linetable->item[best_index].line;
else
best = 0;
+ ALL_PSYMTABS (objfile, p)
+ {
+ if (FILENAME_CMP (symtab->filename, p->filename) != 0)
+ continue;
+ PSYMTAB_TO_SYMTAB (p);
+ }
+
+ /* Get symbol full file name if possible. */
+ symtab_to_fullname (symtab);
+
ALL_SYMTABS (objfile, s)
{
struct linetable *l;
int ind;
- if (!STREQ (symtab->filename, s->filename))
+ if (FILENAME_CMP (symtab->filename, s->filename) != 0)
continue;
+ if (symtab->fullname != NULL
+ && symtab_to_fullname (s) != NULL
+ && FILENAME_CMP (symtab->fullname, s->fullname) != 0)
+ continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact);
if (ind >= 0)
@@ -2164,11 +2608,11 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
static int
-find_line_common (register struct linetable *l, register int lineno,
+find_line_common (struct linetable *l, int lineno,
int *exact_match)
{
- register int i;
- register int len;
+ int i;
+ int len;
/* BEST is the smallest linenumber > LINENO so far seen,
or 0 if none has been seen so far.
@@ -2177,6 +2621,8 @@ find_line_common (register struct linetable *l, register int lineno,
int best_index = -1;
int best = 0;
+ *exact_match = 0;
+
if (lineno <= 0)
return -1;
if (l == 0)
@@ -2185,7 +2631,7 @@ find_line_common (register struct linetable *l, register int lineno,
len = l->nitems;
for (i = 0; i < len; i++)
{
- register struct linetable_entry *item = &(l->item[i]);
+ struct linetable_entry *item = &(l->item[i]);
if (item->line == lineno)
{
@@ -2202,8 +2648,6 @@ find_line_common (register struct linetable *l, register int lineno,
}
/* If we got here, we didn't get an exact match. */
-
- *exact_match = 0;
return best_index;
}
@@ -2217,6 +2661,67 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
return sal.symtab != 0;
}
+/* Given a function start address PC and SECTION, find the first
+ address after the function prologue. */
+CORE_ADDR
+find_function_start_pc (struct gdbarch *gdbarch,
+ CORE_ADDR pc, struct obj_section *section)
+{
+ /* If the function is in an unmapped overlay, use its unmapped LMA address,
+ so that gdbarch_skip_prologue has something unique to work on. */
+ if (section_is_overlay (section) && !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
+ pc += gdbarch_deprecated_function_start_offset (gdbarch);
+ pc = gdbarch_skip_prologue (gdbarch, pc);
+
+ /* For overlays, map pc back into its mapped VMA range. */
+ pc = overlay_mapped_address (pc, section);
+
+ return pc;
+}
+
+/* Given a function start address FUNC_ADDR and SYMTAB, find the first
+ address for that function that has an entry in SYMTAB's line info
+ table. If such an entry cannot be found, return FUNC_ADDR
+ unaltered. */
+CORE_ADDR
+skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
+{
+ CORE_ADDR func_start, func_end;
+ struct linetable *l;
+ int ind, i, len;
+ int best_lineno = 0;
+ CORE_ADDR best_pc = func_addr;
+
+ /* Give up if this symbol has no lineinfo table. */
+ l = LINETABLE (symtab);
+ if (l == NULL)
+ return func_addr;
+
+ /* Get the range for the function's PC values, or give up if we
+ cannot, for some reason. */
+ if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
+ return func_addr;
+
+ /* Linetable entries are ordered by PC values, see the commentary in
+ symtab.h where `struct linetable' is defined. Thus, the first
+ entry whose PC is in the range [FUNC_START..FUNC_END[ is the
+ address we are looking for. */
+ for (i = 0; i < l->nitems; i++)
+ {
+ struct linetable_entry *item = &(l->item[i]);
+
+ /* Don't use line numbers of zero, they mark special entries in
+ the table. See the commentary on symtab.h before the
+ definition of struct linetable. */
+ if (item->line > 0 && func_start <= item->pc && item->pc < func_end)
+ return item->pc;
+ }
+
+ return func_addr;
+}
+
/* Given a function symbol SYM, find the symtab and line for the start
of the function.
If the argument FUNFIRSTLINE is nonzero, we want the first line
@@ -2225,46 +2730,92 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
struct symtab_and_line
find_function_start_sal (struct symbol *sym, int funfirstline)
{
+ struct block *block = SYMBOL_BLOCK_VALUE (sym);
+ struct objfile *objfile = lookup_objfile_from_block (block);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
CORE_ADDR pc;
struct symtab_and_line sal;
+ struct block *b, *function_block;
- pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- fixup_symbol_section (sym, NULL);
- if (funfirstline)
- { /* skip "first line" of function (which is actually its prologue) */
- asection *section = SYMBOL_BFD_SECTION (sym);
- /* If function is in an unmapped overlay, use its unmapped LMA
- address, so that SKIP_PROLOGUE has something unique to work on */
- if (section_is_overlay (section) &&
- !section_is_mapped (section))
- pc = overlay_unmapped_address (pc, section);
+ struct cleanup *old_chain;
- pc += FUNCTION_START_OFFSET;
- pc = SKIP_PROLOGUE (pc);
+ old_chain = save_current_space_and_thread ();
+ switch_to_program_space_and_thread (objfile->pspace);
- /* For overlays, map pc back into its mapped VMA range */
- pc = overlay_mapped_address (pc, section);
+ pc = BLOCK_START (block);
+ fixup_symbol_section (sym, objfile);
+ if (funfirstline)
+ {
+ /* Skip "first line" of function (which is actually its prologue). */
+ pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym));
}
- sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
-#ifdef PROLOGUE_FIRSTLINE_OVERLAP
- /* Convex: no need to suppress code on first line, if any */
- sal.pc = pc;
-#else
- /* Check if SKIP_PROLOGUE left us in mid-line, and the next
+ /* Check if gdbarch_skip_prologue left us in mid-line, and the next
line is still part of the same function. */
if (sal.pc != pc
- && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
- && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+ && BLOCK_START (block) <= sal.end
+ && sal.end < BLOCK_END (block))
{
/* First pc of next line */
pc = sal.end;
/* Recalculate the line number (might not be N+1). */
- sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
+ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
}
+
+ /* On targets with executable formats that don't have a concept of
+ constructors (ELF with .init has, PE doesn't), gcc emits a call
+ to `__main' in `main' between the prologue and before user
+ code. */
+ if (funfirstline
+ && gdbarch_skip_main_prologue_p (gdbarch)
+ && SYMBOL_LINKAGE_NAME (sym)
+ && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
+ {
+ pc = gdbarch_skip_main_prologue (gdbarch, pc);
+ /* Recalculate the line number (might not be N+1). */
+ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
+ }
+
+ /* If we still don't have a valid source line, try to find the first
+ PC in the lineinfo table that belongs to the same function. This
+ happens with COFF debug info, which does not seem to have an
+ entry in lineinfo table for the code after the prologue which has
+ no direct relation to source. For example, this was found to be
+ the case with the DJGPP target using "gcc -gcoff" when the
+ compiler inserted code after the prologue to make sure the stack
+ is aligned. */
+ if (funfirstline && sal.symtab == NULL)
+ {
+ pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
+ /* Recalculate the line number. */
+ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
+ }
+
sal.pc = pc;
-#endif
+ sal.pspace = objfile->pspace;
+
+ /* Check if we are now inside an inlined function. If we can,
+ use the call site of the function instead. */
+ b = block_for_pc_sect (sal.pc, SYMBOL_OBJ_SECTION (sym));
+ function_block = NULL;
+ while (b != NULL)
+ {
+ if (BLOCK_FUNCTION (b) != NULL && block_inlined_p (b))
+ function_block = b;
+ else if (BLOCK_FUNCTION (b) != NULL)
+ break;
+ b = BLOCK_SUPERBLOCK (b);
+ }
+ if (function_block != NULL
+ && SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0)
+ {
+ sal.line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
+ sal.symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block));
+ }
+ do_cleanups (old_chain);
return sal;
}
@@ -2293,7 +2844,7 @@ operator_chars (char *p, char **end)
if (isalpha (*p) || *p == '_' || *p == '$')
{
- register char *q = p + 1;
+ char *q = p + 1;
while (isalnum (*q) || *q == '_' || *q == '$')
q++;
*end = q;
@@ -2315,16 +2866,16 @@ operator_chars (char *p, char **end)
else if (p[1] == '[')
{
if (p[2] == ']')
- error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+ error (_("mismatched quoting on brackets, try 'operator\\[\\]'"));
else if (p[2] == '\\' && p[3] == ']')
{
*end = p + 4; /* 'operator\[\]' */
return p;
}
else
- error ("nothing is allowed between '[' and ']'");
+ error (_("nothing is allowed between '[' and ']'"));
}
- else
+ else
{
/* Gratuitous qoute: skip it and move on. */
p++;
@@ -2378,21 +2929,21 @@ operator_chars (char *p, char **end)
return p;
case '(':
if (p[1] != ')')
- error ("`operator ()' must be specified without whitespace in `()'");
+ error (_("`operator ()' must be specified without whitespace in `()'"));
*end = p + 2;
return p;
case '?':
if (p[1] != ':')
- error ("`operator ?:' must be specified without whitespace in `?:'");
+ error (_("`operator ?:' must be specified without whitespace in `?:'"));
*end = p + 2;
return p;
case '[':
if (p[1] != ']')
- error ("`operator []' must be specified without whitespace in `[]'");
+ error (_("`operator []' must be specified without whitespace in `[]'"));
*end = p + 2;
return p;
default:
- error ("`operator %s' not supported", p);
+ error (_("`operator %s' not supported"), p);
break;
}
@@ -2449,7 +3000,7 @@ filename_seen (const char *file, int add, int *first)
NAME is the name to print and *FIRST is nonzero if this is the first
name printed. Set *FIRST to zero. */
static void
-output_source_filename (char *name, int *first)
+output_source_filename (const char *name, int *first)
{
/* Since a single source file can result in several partial symbol
tables, we need to avoid printing it more than once. Note: if
@@ -2483,14 +3034,14 @@ output_source_filename (char *name, int *first)
static void
sources_info (char *ignore, int from_tty)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
int first;
if (!have_full_symbols () && !have_partial_symbols ())
{
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
}
printf_filtered ("Source files for which symbols have been read in:\n\n");
@@ -2498,7 +3049,8 @@ sources_info (char *ignore, int from_tty)
first = 1;
ALL_SYMTABS (objfile, s)
{
- output_source_filename (s->filename, &first);
+ const char *fullname = symtab_to_fullname (s);
+ output_source_filename (fullname ? fullname : s->filename, &first);
}
printf_filtered ("\n\n");
@@ -2509,7 +3061,8 @@ sources_info (char *ignore, int from_tty)
{
if (!ps->readin)
{
- output_source_filename (ps->filename, &first);
+ const char *fullname = psymtab_to_fullname (ps);
+ output_source_filename (fullname ? fullname : ps->filename, &first);
}
}
printf_filtered ("\n");
@@ -2567,8 +3120,8 @@ compare_search_syms (const void *sa, const void *sb)
struct symbol_search **sym_a = (struct symbol_search **) sa;
struct symbol_search **sym_b = (struct symbol_search **) sb;
- return strcmp (SYMBOL_SOURCE_NAME ((*sym_a)->symbol),
- SYMBOL_SOURCE_NAME ((*sym_b)->symbol));
+ return strcmp (SYMBOL_PRINT_NAME ((*sym_a)->symbol),
+ SYMBOL_PRINT_NAME ((*sym_b)->symbol));
}
/* Sort the ``nfound'' symbols in the list after prevtail. Leave
@@ -2610,10 +3163,9 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound)
returning the results in *MATCHES.
Only symbols of KIND are searched:
- FUNCTIONS_NAMESPACE - search all functions
- TYPES_NAMESPACE - search all type names
- METHODS_NAMESPACE - search all methods NOT IMPLEMENTED
- VARIABLES_NAMESPACE - search all symbols, excluding functions, type names,
+ FUNCTIONS_DOMAIN - search all functions
+ TYPES_DOMAIN - search all type names
+ VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
and constants (enums)
free_search_symbols should be called when *MATCHES is no longer needed.
@@ -2622,17 +3174,16 @@ sort_search_symbols (struct symbol_search *prevtail, int nfound)
separately alphabetized.
*/
void
-search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
+search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
struct symbol_search **matches)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct blockvector *bv;
- struct blockvector *prev_bv = 0;
- register struct block *b;
- register int i = 0;
- register int j;
- register struct symbol *sym;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct blockvector *bv;
+ struct block *b;
+ int i = 0;
+ struct dict_iterator iter;
+ struct symbol *sym;
struct partial_symbol **psym;
struct objfile *objfile;
struct minimal_symbol *msymbol;
@@ -2659,13 +3210,13 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
struct symbol_search *tail;
struct cleanup *old_chain = NULL;
- if (kind < VARIABLES_NAMESPACE)
- error ("must search on specific namespace");
+ if (kind < VARIABLES_DOMAIN)
+ error (_("must search on specific domain"));
- ourtype = types[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype2 = types2[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype3 = types3[(int) (kind - VARIABLES_NAMESPACE)];
- ourtype4 = types4[(int) (kind - VARIABLES_NAMESPACE)];
+ ourtype = types[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype3 = types3[(int) (kind - VARIABLES_DOMAIN)];
+ ourtype4 = types4[(int) (kind - VARIABLES_DOMAIN)];
sr = *matches = NULL;
tail = NULL;
@@ -2703,7 +3254,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
}
if (0 != (val = re_comp (regexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ error (_("Invalid regexp (%s): %s"), val, regexp);
}
/* Search through the partial symtabs *first* for all symbols
@@ -2743,14 +3294,20 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
QUIT;
/* If it would match (logic taken from loop below)
- load the file and go on to the next one */
+ load the file and go on to the next one. We check the
+ filename here, but that's a bit bogus: we don't know
+ what file it really comes from until we have full
+ symtabs. The symbol might be in a header file included by
+ this psymtab. This only affects Insight. */
if (file_matches (ps->filename, files, nfiles)
- && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
- && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (*psym) != LOC_BLOCK)
- || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
- || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
- || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+ && ((regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0)
+ && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (*psym) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK
+ && SYMBOL_CLASS (*psym) != LOC_CONST)
+ || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))))
{
PSYMTAB_TO_SYMTAB (ps);
keep_going = 0;
@@ -2773,24 +3330,33 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
any matching symbols without debug info.
*/
- if (nfiles == 0 && (kind == VARIABLES_NAMESPACE || kind == FUNCTIONS_NAMESPACE))
+ if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN))
{
ALL_MSYMBOLS (objfile, msymbol)
{
+ QUIT;
+
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ if (regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
{
if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
{
- if (kind == FUNCTIONS_NAMESPACE
- || lookup_symbol (SYMBOL_NAME (msymbol),
+ /* FIXME: carlton/2003-02-04: Given that the
+ semantics of lookup_symbol keeps on changing
+ slightly, it would be a nice idea if we had a
+ function lookup_symbol_minsym that found the
+ symbol associated to a given minimal symbol (if
+ any). */
+ if (kind == FUNCTIONS_DOMAIN
+ || lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
(struct block *) NULL,
- VAR_NAMESPACE,
- 0, (struct symtab **) NULL) == NULL)
+ VAR_DOMAIN, 0)
+ == NULL)
found_misc = 1;
}
}
@@ -2798,36 +3364,33 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
}
}
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
bv = BLOCKVECTOR (s);
- /* Often many files share a blockvector.
- Scan each blockvector only once so that
- we don't get every symbol many times.
- It happens that the first symtab in the list
- for any given blockvector is the main file. */
- if (bv != prev_bv)
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
struct symbol_search *prevtail = tail;
int nfound = 0;
b = BLOCKVECTOR_BLOCK (bv, i);
- ALL_BLOCK_SYMBOLS (b, j, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
+ struct symtab *real_symtab = SYMBOL_SYMTAB (sym);
QUIT;
- if (file_matches (s->filename, files, nfiles)
- && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
- && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+
+ if (file_matches (real_symtab->filename, files, nfiles)
+ && ((regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
+ && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
&& SYMBOL_CLASS (sym) != LOC_BLOCK
&& SYMBOL_CLASS (sym) != LOC_CONST)
- || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
- || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+ || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
{
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
psr->block = i;
- psr->symtab = s;
+ psr->symtab = real_symtab;
psr->symbol = sym;
psr->msymbol = NULL;
psr->next = NULL;
@@ -2855,31 +3418,33 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
tail = sort_search_symbols (prevtail, nfound);
}
}
- prev_bv = bv;
}
/* If there are no eyes, avoid all contact. I mean, if there are
no debug symbols, then print directly from the msymbol_vector. */
- if (found_misc || kind != FUNCTIONS_NAMESPACE)
+ if (found_misc || kind != FUNCTIONS_DOMAIN)
{
ALL_MSYMBOLS (objfile, msymbol)
{
+ QUIT;
+
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
MSYMBOL_TYPE (msymbol) == ourtype4)
{
- if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+ if (regexp == NULL
+ || re_exec (SYMBOL_NATURAL_NAME (msymbol)) != 0)
{
/* Functions: Look up by address. */
- if (kind != FUNCTIONS_NAMESPACE ||
+ if (kind != FUNCTIONS_DOMAIN ||
(0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))))
{
/* Variables/Absolutes: Look up by name */
- if (lookup_symbol (SYMBOL_NAME (msymbol),
- (struct block *) NULL, VAR_NAMESPACE,
- 0, (struct symtab **) NULL) == NULL)
+ if (lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
+ (struct block *) NULL, VAR_DOMAIN, 0)
+ == NULL)
{
/* match */
psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
@@ -2913,7 +3478,7 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
regarding the match to gdb_stdout.
*/
static void
-print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
+print_symbol_info (domain_enum kind, struct symtab *s, struct symbol *sym,
int block, char *last)
{
if (last == NULL || strcmp (last, s->filename) != 0)
@@ -2923,49 +3488,25 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
fputs_filtered (":\n", gdb_stdout);
}
- if (kind != TYPES_NAMESPACE && block == STATIC_BLOCK)
+ if (kind != TYPES_DOMAIN && block == STATIC_BLOCK)
printf_filtered ("static ");
/* Typedef that is not a C++ class */
- if (kind == TYPES_NAMESPACE
- && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
+ if (kind == TYPES_DOMAIN
+ && SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
typedef_print (SYMBOL_TYPE (sym), sym, gdb_stdout);
/* variable, func, or typedef-that-is-c++-class */
- else if (kind < TYPES_NAMESPACE ||
- (kind == TYPES_NAMESPACE &&
- SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE))
+ else if (kind < TYPES_DOMAIN ||
+ (kind == TYPES_DOMAIN &&
+ SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN))
{
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
- ? "" : SYMBOL_SOURCE_NAME (sym)),
+ ? "" : SYMBOL_PRINT_NAME (sym)),
gdb_stdout, 0);
printf_filtered (";\n");
}
- else
- {
-#if 0
- /* Tiemann says: "info methods was never implemented." */
- char *demangled_name;
- c_type_print_base (TYPE_FN_FIELD_TYPE (t, block),
- gdb_stdout, 0, 0);
- c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (t, block),
- gdb_stdout, 0);
- if (TYPE_FN_FIELD_STUB (t, block))
- check_stub_method (TYPE_DOMAIN_TYPE (type), j, block);
- demangled_name =
- cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, block),
- DMGL_ANSI | DMGL_PARAMS);
- if (demangled_name == NULL)
- fprintf_filtered (stream, "",
- TYPE_FN_FIELD_PHYSNAME (t, block));
- else
- {
- fputs_filtered (demangled_name, stream);
- xfree (demangled_name);
- }
-#endif
- }
}
/* This help function for symtab_symbol_info() prints information
@@ -2974,17 +3515,18 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
static void
print_msymbol_info (struct minimal_symbol *msymbol)
{
+ struct gdbarch *gdbarch = get_objfile_arch (msymbol_objfile (msymbol));
char *tmp;
- if (TARGET_ADDR_BIT <= 32)
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
- & (CORE_ADDR) 0xffffffff,
- "08l");
+ if (gdbarch_addr_bit (gdbarch) <= 32)
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ & (CORE_ADDR) 0xffffffff,
+ 8);
else
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
- "016l");
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ 16);
printf_filtered ("%s %s\n",
- tmp, SYMBOL_SOURCE_NAME (msymbol));
+ tmp, SYMBOL_PRINT_NAME (msymbol));
}
/* This is the guts of the commands "info functions", "info types", and
@@ -2993,7 +3535,7 @@ print_msymbol_info (struct minimal_symbol *msymbol)
matches.
*/
static void
-symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
+symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
{
static char *classnames[]
=
@@ -3011,7 +3553,7 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
printf_filtered (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
- classnames[(int) (kind - VARIABLES_NAMESPACE)], regexp);
+ classnames[(int) (kind - VARIABLES_DOMAIN)], regexp);
for (p = symbols; p != NULL; p = p->next)
{
@@ -3043,30 +3585,21 @@ symtab_symbol_info (char *regexp, namespace_enum kind, int from_tty)
static void
variables_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, VARIABLES_NAMESPACE, from_tty);
+ symtab_symbol_info (regexp, VARIABLES_DOMAIN, from_tty);
}
static void
functions_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
+ symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty);
}
static void
types_info (char *regexp, int from_tty)
{
- symtab_symbol_info (regexp, TYPES_NAMESPACE, from_tty);
-}
-
-#if 0
-/* Tiemann says: "info methods was never implemented." */
-static void
-methods_info (char *regexp)
-{
- symtab_symbol_info (regexp, METHODS_NAMESPACE, 0, from_tty);
+ symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty);
}
-#endif /* 0 */
/* Breakpoint all functions matching regular expression. */
@@ -3083,22 +3616,22 @@ rbreak_command (char *regexp, int from_tty)
struct symbol_search *p;
struct cleanup *old_chain;
- search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
+ search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss);
old_chain = make_cleanup_free_search_symbols (ss);
for (p = ss; p != NULL; p = p->next)
{
if (p->msymbol == NULL)
{
- char *string = (char *) alloca (strlen (p->symtab->filename)
- + strlen (SYMBOL_NAME (p->symbol))
- + 4);
+ char *string = alloca (strlen (p->symtab->filename)
+ + strlen (SYMBOL_LINKAGE_NAME (p->symbol))
+ + 4);
strcpy (string, p->symtab->filename);
strcat (string, ":'");
- strcat (string, SYMBOL_NAME (p->symbol));
+ strcat (string, SYMBOL_LINKAGE_NAME (p->symbol));
strcat (string, "'");
break_command (string, from_tty);
- print_symbol_info (FUNCTIONS_NAMESPACE,
+ print_symbol_info (FUNCTIONS_DOMAIN,
p->symtab,
p->symbol,
p->block,
@@ -3106,9 +3639,15 @@ rbreak_command (char *regexp, int from_tty)
}
else
{
- break_command (SYMBOL_NAME (p->msymbol), from_tty);
+ char *string = alloca (strlen (SYMBOL_LINKAGE_NAME (p->msymbol))
+ + 3);
+ strcpy (string, "'");
+ strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol));
+ strcat (string, "'");
+
+ break_command (string, from_tty);
printf_filtered (" %s;\n",
- SYMBOL_SOURCE_NAME (p->msymbol));
+ SYMBOL_PRINT_NAME (p->msymbol));
}
}
@@ -3116,19 +3655,6 @@ rbreak_command (char *regexp, int from_tty)
}
-/* Return Nonzero if block a is lexically nested within block b,
- or if a and b have the same pc range.
- Return zero otherwise. */
-int
-contained_in (struct block *a, struct block *b)
-{
- if (!a || !b)
- return 0;
- return BLOCK_START (a) >= BLOCK_START (b)
- && BLOCK_END (a) <= BLOCK_END (b);
-}
-
-
/* Helper routine for make_symbol_completion_list. */
static int return_val_size;
@@ -3136,17 +3662,8 @@ static int return_val_index;
static char **return_val;
#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
- do { \
- if (SYMBOL_DEMANGLED_NAME (symbol) != NULL) \
- /* Put only the mangled name on the list. */ \
- /* Advantage: "b foo" completes to "b foo(int, int)" */ \
- /* Disadvantage: "b foo__i" doesn't complete. */ \
completion_list_add_name \
- (SYMBOL_DEMANGLED_NAME (symbol), (sym_text), (len), (text), (word)); \
- else \
- completion_list_add_name \
- (SYMBOL_NAME (symbol), (sym_text), (len), (text), (word)); \
- } while (0)
+ (SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
/* Test to see if the symbol specified by SYMNAME (which is already
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
@@ -3201,31 +3718,174 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
}
}
-/* Return a NULL terminated array of all symbols (regardless of class)
- which begin by matching TEXT. If the answer is no symbols, then
- the return value is an array which contains only a NULL pointer.
+/* ObjC: In case we are completing on a selector, look as the msymbol
+ again and feed all the selectors into the mill. */
+
+static void
+completion_list_objc_symbol (struct minimal_symbol *msymbol, char *sym_text,
+ int sym_text_len, char *text, char *word)
+{
+ static char *tmp = NULL;
+ static unsigned int tmplen = 0;
+
+ char *method, *category, *selector;
+ char *tmp2 = NULL;
+
+ method = SYMBOL_NATURAL_NAME (msymbol);
+
+ /* Is it a method? */
+ if ((method[0] != '-') && (method[0] != '+'))
+ return;
+
+ if (sym_text[0] == '[')
+ /* Complete on shortened method method. */
+ completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
+
+ while ((strlen (method) + 1) >= tmplen)
+ {
+ if (tmplen == 0)
+ tmplen = 1024;
+ else
+ tmplen *= 2;
+ tmp = xrealloc (tmp, tmplen);
+ }
+ selector = strchr (method, ' ');
+ if (selector != NULL)
+ selector++;
+
+ category = strchr (method, '(');
+
+ if ((category != NULL) && (selector != NULL))
+ {
+ memcpy (tmp, method, (category - method));
+ tmp[category - method] = ' ';
+ memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ if (sym_text[0] == '[')
+ completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
+ }
+
+ if (selector != NULL)
+ {
+ /* Complete on selector only. */
+ strcpy (tmp, selector);
+ tmp2 = strchr (tmp, ']');
+ if (tmp2 != NULL)
+ *tmp2 = '\0';
+
+ completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ }
+}
+
+/* Break the non-quoted text based on the characters which are in
+ symbols. FIXME: This should probably be language-specific. */
+
+static char *
+language_search_unquoted_string (char *text, char *p)
+{
+ for (; p > text; --p)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ continue;
+ else
+ {
+ if ((current_language->la_language == language_objc))
+ {
+ if (p[-1] == ':') /* might be part of a method name */
+ continue;
+ else if (p[-1] == '[' && (p[-2] == '-' || p[-2] == '+'))
+ p -= 2; /* beginning of a method name */
+ else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')')
+ { /* might be part of a method name */
+ char *t = p;
+
+ /* Seeing a ' ' or a '(' is not conclusive evidence
+ that we are in the middle of a method name. However,
+ finding "-[" or "+[" should be pretty un-ambiguous.
+ Unfortunately we have to find it now to decide. */
+
+ while (t > text)
+ if (isalnum (t[-1]) || t[-1] == '_' ||
+ t[-1] == ' ' || t[-1] == ':' ||
+ t[-1] == '(' || t[-1] == ')')
+ --t;
+ else
+ break;
+
+ if (t[-1] == '[' && (t[-2] == '-' || t[-2] == '+'))
+ p = t - 2; /* method name detected */
+ /* else we leave with p unchanged */
+ }
+ }
+ break;
+ }
+ }
+ return p;
+}
+
+static void
+completion_list_add_fields (struct symbol *sym, char *sym_text,
+ int sym_text_len, char *text, char *word)
+{
+ if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+ struct type *t = SYMBOL_TYPE (sym);
+ enum type_code c = TYPE_CODE (t);
+ int j;
+
+ if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
+ for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+ if (TYPE_FIELD_NAME (t, j))
+ completion_list_add_name (TYPE_FIELD_NAME (t, j),
+ sym_text, sym_text_len, text, word);
+ }
+}
+
+/* Type of the user_data argument passed to add_macro_name. The
+ contents are simply whatever is needed by
+ completion_list_add_name. */
+struct add_macro_name_data
+{
+ char *sym_text;
+ int sym_text_len;
+ char *text;
+ char *word;
+};
- Problem: All of the symbols have to be copied because readline frees them.
- I'm not going to worry about this; hopefully there won't be that many. */
+/* A callback used with macro_for_each and macro_for_each_in_scope.
+ This adds a macro's name to the current completion list. */
+static void
+add_macro_name (const char *name, const struct macro_definition *ignore,
+ void *user_data)
+{
+ struct add_macro_name_data *datum = (struct add_macro_name_data *) user_data;
+ completion_list_add_name ((char *) name,
+ datum->sym_text, datum->sym_text_len,
+ datum->text, datum->word);
+}
char **
-make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct minimal_symbol *msymbol;
- register struct objfile *objfile;
- register struct block *b, *surrounding_static_block = 0;
- register int i, j;
+ /* Problem: All of the symbols have to be copied because readline
+ frees them. I'm not going to worry about this; hopefully there
+ won't be that many. */
+
+ struct symbol *sym;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct block *b;
+ const struct block *surrounding_static_block, *surrounding_global_block;
+ struct dict_iterator iter;
struct partial_symbol **psym;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
/* Length of sym_text. */
int sym_text_len;
- /* Now look for the symbol we are supposed to complete on.
- FIXME: This should be language-specific. */
+ /* Now look for the symbol we are supposed to complete on. */
{
char *p;
char quote_found;
@@ -3268,7 +3928,8 @@ make_symbol_completion_list (char *text, char *word)
which are in symbols. */
while (p > text)
{
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
+ || p[-1] == ':')
--p;
else
break;
@@ -3323,83 +3984,134 @@ make_symbol_completion_list (char *text, char *word)
{
QUIT;
COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+
+ completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
}
/* Search upwards from currently selected frame (so that we can
- complete on local vars. */
+ complete on local vars). Also catch fields of types defined in
+ this places which match our text string. Only complete on types
+ visible from current context. */
+
+ b = get_selected_block (0);
+ surrounding_static_block = block_static_block (b);
+ surrounding_global_block = block_global_block (b);
+ if (surrounding_static_block != NULL)
+ while (b != surrounding_static_block)
+ {
+ QUIT;
- for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
- {
- if (!BLOCK_SUPERBLOCK (b))
- {
- surrounding_static_block = b; /* For elmin of dups */
- }
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+ word);
+ completion_list_add_fields (sym, sym_text, sym_text_len, text,
+ word);
+ }
- /* Also catch fields of types defined in this places which match our
- text string. Only complete on types visible from current context. */
+ /* Stop when we encounter an enclosing function. Do not stop for
+ non-inlined functions - the locals of the enclosing function
+ are in scope for a nested function. */
+ if (BLOCK_FUNCTION (b) != NULL && block_inlined_p (b))
+ break;
+ b = BLOCK_SUPERBLOCK (b);
+ }
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
- if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- {
- struct type *t = SYMBOL_TYPE (sym);
- enum type_code c = TYPE_CODE (t);
+ /* Add fields from the file's types; symbols will be added below. */
- if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
- {
- for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
- {
- if (TYPE_FIELD_NAME (t, j))
- {
- completion_list_add_name (TYPE_FIELD_NAME (t, j),
- sym_text, sym_text_len, text, word);
- }
- }
- }
- }
- }
- }
+ if (surrounding_static_block != NULL)
+ ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+
+ if (surrounding_global_block != NULL)
+ ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
}
- ALL_SYMTABS (objfile, s)
+ ALL_PRIMARY_SYMTABS (objfile, s)
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
}
+ if (current_language->la_macro_expansion == macro_expansion_c)
+ {
+ struct macro_scope *scope;
+ struct add_macro_name_data datum;
+
+ datum.sym_text = sym_text;
+ datum.sym_text_len = sym_text_len;
+ datum.text = text;
+ datum.word = word;
+
+ /* Add any macros visible in the default scope. Note that this
+ may yield the occasional wrong result, because an expression
+ might be evaluated in a scope other than the default. For
+ example, if the user types "break file:line if ", the
+ resulting expression will be evaluated at "file:line" -- but
+ at there does not seem to be a way to detect this at
+ completion time. */
+ scope = default_macro_scope ();
+ if (scope)
+ {
+ macro_for_each_in_scope (scope->file, scope->line,
+ add_macro_name, &datum);
+ xfree (scope);
+ }
+
+ /* User-defined macros are always visible. */
+ macro_for_each (macro_user_macros, add_macro_name, &datum);
+ }
+
return (return_val);
}
+/* Return a NULL terminated array of all symbols (regardless of class)
+ which begin by matching TEXT. If the answer is no symbols, then
+ the return value is an array which contains only a NULL pointer. */
+
+char **
+make_symbol_completion_list (char *text, char *word)
+{
+ return current_language->la_make_symbol_completion_list (text, word);
+}
+
+/* Like make_symbol_completion_list, but suitable for use as a
+ completion function. */
+
+char **
+make_symbol_completion_list_fn (struct cmd_list_element *ignore,
+ char *text, char *word)
+{
+ return make_symbol_completion_list (text, word);
+}
+
/* Like make_symbol_completion_list, but returns a list of symbols
defined in a source file FILE. */
char **
make_file_symbol_completion_list (char *text, char *word, char *srcfile)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct block *b;
- register int i;
+ struct symbol *sym;
+ struct symtab *s;
+ struct block *b;
+ struct dict_iterator iter;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
/* Length of sym_text. */
@@ -3445,16 +4157,8 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
}
else
{
- /* It is not a quoted string. Break it based on the characters
- which are in symbols. */
- while (p > text)
- {
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
- --p;
- else
- break;
- }
- sym_text = p;
+ /* Not a quoted string. */
+ sym_text = language_search_unquoted_string (text, p);
}
}
@@ -3486,13 +4190,13 @@ make_file_symbol_completion_list (char *text, char *word, char *srcfile)
symbols which match. */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ 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);
- ALL_BLOCK_SYMBOLS (b, i, sym)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
@@ -3567,9 +4271,9 @@ not_interesting_fname (const char *fname)
char **
make_source_files_completion_list (char *text, char *word)
{
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
int first = 1;
int list_alloced = 1;
int list_used = 0;
@@ -3668,7 +4372,7 @@ make_source_files_completion_list (char *text, char *word)
*/
int
-in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
+in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
{
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
@@ -3682,7 +4386,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
- The minimal symbols and partial symbols, which can usually tell
us the starting and ending addresses of a function.
- If we know the function's start address, we can call the
- architecture-defined SKIP_PROLOGUE function to analyze the
+ architecture-defined gdbarch_skip_prologue function to analyze the
instruction stream and guess where the prologue ends.
- Our `func_start' argument; if non-zero, this is the caller's
best guess as to the function's entry point. At the time of
@@ -3700,7 +4404,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
if (! func_start)
return 1; /* We *might* be in a prologue. */
- prologue_end = SKIP_PROLOGUE (func_start);
+ prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
return func_start <= pc && pc < prologue_end;
}
@@ -3724,7 +4428,7 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
/* We don't have any good line number info, so use the minsym
information, together with the architecture-specific prologue
scanning code. */
- CORE_ADDR prologue_end = SKIP_PROLOGUE (func_addr);
+ CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
return func_addr <= pc && pc < prologue_end;
}
@@ -3733,281 +4437,440 @@ in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
return func_addr <= pc && pc < sal.end;
}
+/* Given PC at the function's start address, attempt to find the
+ prologue end using SAL information. Return zero if the skip fails.
-/* Begin overload resolution functions */
+ A non-optimized prologue traditionally has one SAL for the function
+ and a second for the function body. A single line function has
+ them both pointing at the same line.
-static char *
-remove_params (const char *demangled_name)
-{
- const char *argp;
- char *new_name;
- int depth;
+ An optimized prologue is similar but the prologue may contain
+ instructions (SALs) from the instruction body. Need to skip those
+ while not getting into the function body.
- if (demangled_name == NULL)
- return NULL;
+ The functions end point and an increasing SAL line are used as
+ indicators of the prologue's endpoint.
- /* First find the end of the arg list. */
- argp = strrchr (demangled_name, ')');
- if (argp == NULL)
- return NULL;
+ This code is based on the function refine_prologue_limit (versions
+ found in both ia64 and ppc). */
+
+CORE_ADDR
+skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
+{
+ struct symtab_and_line prologue_sal;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+ struct block *bl;
- /* Back up to the beginning. */
- depth = 1;
+ /* Get an initial range for the function. */
+ find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+ start_pc += gdbarch_deprecated_function_start_offset (gdbarch);
- while (argp-- > demangled_name)
+ prologue_sal = find_pc_line (start_pc, 0);
+ if (prologue_sal.line != 0)
{
- if (*argp == ')')
- depth ++;
- else if (*argp == '(')
+ /* For langauges other than assembly, treat two consecutive line
+ entries at the same address as a zero-instruction prologue.
+ The GNU assembler emits separate line notes for each instruction
+ in a multi-instruction macro, but compilers generally will not
+ do this. */
+ if (prologue_sal.symtab->language != language_asm)
+ {
+ struct linetable *linetable = LINETABLE (prologue_sal.symtab);
+ int exact;
+ int idx = 0;
+
+ /* Skip any earlier lines, and any end-of-sequence marker
+ from a previous function. */
+ while (linetable->item[idx].pc != prologue_sal.pc
+ || linetable->item[idx].line == 0)
+ idx++;
+
+ if (idx+1 < linetable->nitems
+ && linetable->item[idx+1].line != 0
+ && linetable->item[idx+1].pc == start_pc)
+ return start_pc;
+ }
+
+ /* If there is only one sal that covers the entire function,
+ then it is probably a single line function, like
+ "foo(){}". */
+ if (prologue_sal.end >= end_pc)
+ return 0;
+
+ while (prologue_sal.end < end_pc)
{
- depth --;
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (prologue_sal.end, 0);
+ if (sal.line == 0)
+ break;
+ /* Assume that a consecutive SAL for the same (or larger)
+ line mark the prologue -> body transition. */
+ if (sal.line >= prologue_sal.line)
+ break;
- if (depth == 0)
+ /* The line number is smaller. Check that it's from the
+ same function, not something inlined. If it's inlined,
+ then there is no point comparing the line numbers. */
+ bl = block_for_pc (prologue_sal.end);
+ while (bl)
+ {
+ if (block_inlined_p (bl))
+ break;
+ if (BLOCK_FUNCTION (bl))
+ {
+ bl = NULL;
+ break;
+ }
+ bl = BLOCK_SUPERBLOCK (bl);
+ }
+ if (bl != NULL)
break;
+
+ /* The case in which compiler's optimizer/scheduler has
+ moved instructions into the prologue. We look ahead in
+ the function looking for address ranges whose
+ corresponding line number is less the first one that we
+ found for the function. This is more conservative then
+ refine_prologue_limit which scans a large number of SALs
+ looking for any in the prologue */
+ prologue_sal = sal;
}
}
- if (depth != 0)
- internal_error (__FILE__, __LINE__,
- "bad demangled name %s\n", demangled_name);
- while (argp[-1] == ' ' && argp > demangled_name)
- argp --;
- new_name = xmalloc (argp - demangled_name + 1);
- memcpy (new_name, demangled_name, argp - demangled_name);
- new_name[argp - demangled_name] = '\0';
- return new_name;
+ if (prologue_sal.end < end_pc)
+ /* Return the end of this line, or zero if we could not find a
+ line. */
+ return prologue_sal.end;
+ else
+ /* Don't return END_PC, which is past the end of the function. */
+ return prologue_sal.pc;
}
+
+struct symtabs_and_lines
+decode_line_spec (char *string, int funfirstline)
+{
+ struct symtabs_and_lines sals;
+ struct symtab_and_line cursal;
-/* Helper routine for make_symbol_completion_list. */
-
-static int sym_return_val_size;
-static int sym_return_val_index;
-static struct symbol **sym_return_val;
-
-/* Test to see if the symbol specified by SYMNAME (which is already
- demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
- characters. If so, add it to the current completion list. */
+ if (string == 0)
+ error (_("Empty line specification."));
-static void
-overload_list_add_symbol (struct symbol *sym, char *oload_name)
-{
- int newsize;
- int i;
- char *sym_name;
+ /* We use whatever is set as the current source line. We do not try
+ and get a default or it will recursively call us! */
+ cursal = get_current_source_symtab_and_line ();
- /* If there is no type information, we can't do anything, so skip */
- if (SYMBOL_TYPE (sym) == NULL)
- return;
+ sals = decode_line_1 (&string, funfirstline,
+ cursal.symtab, cursal.line,
+ (char ***) NULL, NULL);
- /* skip any symbols that we've already considered. */
- for (i = 0; i < sym_return_val_index; ++i)
- if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
- return;
+ if (*string)
+ error (_("Junk at end of line specification: %s"), string);
+ return sals;
+}
- /* Get the demangled name without parameters */
- sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
- if (!sym_name)
- return;
+/* Track MAIN */
+static char *name_of_main;
- /* skip symbols that cannot match */
- if (strcmp (sym_name, oload_name) != 0)
+void
+set_main_name (const char *name)
+{
+ if (name_of_main != NULL)
{
- xfree (sym_name);
- return;
+ xfree (name_of_main);
+ name_of_main = NULL;
}
-
- xfree (sym_name);
-
- /* We have a match for an overload instance, so add SYM to the current list
- * of overload instances */
- if (sym_return_val_index + 3 > sym_return_val_size)
+ if (name != NULL)
{
- newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
- sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
+ name_of_main = xstrdup (name);
}
- sym_return_val[sym_return_val_index++] = sym;
- sym_return_val[sym_return_val_index] = NULL;
}
-/* Return a null-terminated list of pointers to function symbols that
- * match name of the supplied symbol FSYM.
- * This is used in finding all overloaded instances of a function name.
- * This has been modified from make_symbol_completion_list. */
+/* Deduce the name of the main procedure, and set NAME_OF_MAIN
+ accordingly. */
-
-struct symbol **
-make_symbol_overload_list (struct symbol *fsym)
+static void
+find_main_name (void)
{
- register struct symbol *sym;
- register struct symtab *s;
- register struct partial_symtab *ps;
- register struct objfile *objfile;
- register struct block *b, *surrounding_static_block = 0;
- register int i;
- /* The name we are completing on. */
- char *oload_name = NULL;
- /* Length of name. */
- int oload_name_len = 0;
-
- /* Look for the symbol we are supposed to complete on. */
-
- oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
- if (!oload_name)
+ const char *new_main_name;
+
+ /* Try to see if the main procedure is in Ada. */
+ /* FIXME: brobecker/2005-03-07: Another way of doing this would
+ be to add a new method in the language vector, and call this
+ method for each language until one of them returns a non-empty
+ name. This would allow us to remove this hard-coded call to
+ an Ada function. It is not clear that this is a better approach
+ at this point, because all methods need to be written in a way
+ such that false positives never be returned. For instance, it is
+ important that a method does not return a wrong name for the main
+ procedure if the main procedure is actually written in a different
+ language. It is easy to guaranty this with Ada, since we use a
+ special symbol generated only when the main in Ada to find the name
+ of the main procedure. It is difficult however to see how this can
+ be guarantied for languages such as C, for instance. This suggests
+ that order of call for these methods becomes important, which means
+ a more complicated approach. */
+ new_main_name = ada_main_name ();
+ if (new_main_name != NULL)
{
- sym_return_val_size = 1;
- sym_return_val = (struct symbol **) xmalloc (2 * sizeof (struct symbol *));
- sym_return_val[0] = fsym;
- sym_return_val[1] = NULL;
+ set_main_name (new_main_name);
+ return;
+ }
- return sym_return_val;
+ new_main_name = pascal_main_name ();
+ if (new_main_name != NULL)
+ {
+ set_main_name (new_main_name);
+ return;
}
- oload_name_len = strlen (oload_name);
- sym_return_val_size = 100;
- sym_return_val_index = 0;
- sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
- sym_return_val[0] = NULL;
+ /* The languages above didn't identify the name of the main procedure.
+ Fallback to "main". */
+ set_main_name ("main");
+}
- /* Look through the partial symtabs for all symbols which begin
- by matching OLOAD_NAME. Make sure we read that symbol table in. */
+char *
+main_name (void)
+{
+ if (name_of_main == NULL)
+ find_main_name ();
- ALL_PSYMTABS (objfile, ps)
- {
- struct partial_symbol **psym;
+ return name_of_main;
+}
- /* If the psymtab's been read in we'll get it when we search
- through the blockvector. */
- if (ps->readin)
- continue;
+/* Handle ``executable_changed'' events for the symtab module. */
- for (psym = objfile->global_psymbols.list + ps->globals_offset;
- psym < (objfile->global_psymbols.list + ps->globals_offset
- + ps->n_global_syms);
- psym++)
- {
- /* If interrupted, then quit. */
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
+static void
+symtab_observer_executable_changed (void)
+{
+ /* NAME_OF_MAIN may no longer be the same, so reset it for now. */
+ set_main_name (NULL);
+}
- for (psym = objfile->static_psymbols.list + ps->statics_offset;
- psym < (objfile->static_psymbols.list + ps->statics_offset
- + ps->n_static_syms);
- psym++)
- {
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
- }
+/* Helper to expand_line_sal below. Appends new sal to SAL,
+ initializing it from SYMTAB, LINENO and PC. */
+static void
+append_expanded_sal (struct symtabs_and_lines *sal,
+ struct program_space *pspace,
+ struct symtab *symtab,
+ int lineno, CORE_ADDR pc)
+{
+ sal->sals = xrealloc (sal->sals,
+ sizeof (sal->sals[0])
+ * (sal->nelts + 1));
+ init_sal (sal->sals + sal->nelts);
+ sal->sals[sal->nelts].pspace = pspace;
+ sal->sals[sal->nelts].symtab = symtab;
+ sal->sals[sal->nelts].section = NULL;
+ sal->sals[sal->nelts].end = 0;
+ sal->sals[sal->nelts].line = lineno;
+ sal->sals[sal->nelts].pc = pc;
+ ++sal->nelts;
+}
- /* Search upwards from currently selected frame (so that we can
- complete on local vars. */
+/* Helper to expand_line_sal below. Search in the symtabs for any
+ linetable entry that exactly matches FULLNAME and LINENO and append
+ them to RET. If FULLNAME is NULL or if a symtab has no full name,
+ use FILENAME and LINENO instead. If there is at least one match,
+ return 1; otherwise, return 0, and return the best choice in BEST_ITEM
+ and BEST_SYMTAB. */
- for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+static int
+append_exact_match_to_sals (char *filename, char *fullname, int lineno,
+ struct symtabs_and_lines *ret,
+ struct linetable_entry **best_item,
+ struct symtab **best_symtab)
+{
+ struct program_space *pspace;
+ struct objfile *objfile;
+ struct symtab *symtab;
+ int exact = 0;
+ int j;
+ *best_item = 0;
+ *best_symtab = 0;
+
+ ALL_PSPACES (pspace)
+ ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
{
- if (!BLOCK_SUPERBLOCK (b))
+ if (FILENAME_CMP (filename, symtab->filename) == 0)
{
- surrounding_static_block = b; /* For elimination of dups */
- }
+ struct linetable *l;
+ int len;
+ if (fullname != NULL
+ && symtab_to_fullname (symtab) != NULL
+ && FILENAME_CMP (fullname, symtab->fullname) != 0)
+ continue;
+ l = LINETABLE (symtab);
+ if (!l)
+ continue;
+ len = l->nitems;
- /* Also catch fields of types defined in this places which match our
- text string. Only complete on types visible from current context. */
+ for (j = 0; j < len; j++)
+ {
+ struct linetable_entry *item = &(l->item[j]);
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
+ if (item->line == lineno)
+ {
+ exact = 1;
+ append_expanded_sal (ret, objfile->pspace,
+ symtab, lineno, item->pc);
+ }
+ else if (!exact && item->line > lineno
+ && (*best_item == NULL
+ || item->line < (*best_item)->line))
+ {
+ *best_item = item;
+ *best_symtab = symtab;
+ }
+ }
}
}
-
- /* Go through the symtabs and check the externs and statics for
- symbols which match. */
-
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
- }
- }
-
- ALL_SYMTABS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- ALL_BLOCK_SYMBOLS (b, i, sym)
- {
- overload_list_add_symbol (sym, oload_name);
- }
- }
-
- xfree (oload_name);
-
- return (sym_return_val);
+ return exact;
}
-/* End of overload resolution functions */
-
+/* Compute a set of all sals in all program spaces that correspond to
+ same file and line as SAL and return those. If there are several
+ sals that belong to the same block, only one sal for the block is
+ included in results. */
+
struct symtabs_and_lines
-decode_line_spec (char *string, int funfirstline)
+expand_line_sal (struct symtab_and_line sal)
{
- struct symtabs_and_lines sals;
- if (string == 0)
- error ("Empty line specification.");
- sals = decode_line_1 (&string, funfirstline,
- current_source_symtab, current_source_line,
- (char ***) NULL);
- if (*string)
- error ("Junk at end of line specification: %s", string);
- return sals;
-}
+ struct symtabs_and_lines ret, this_line;
+ int i, j;
+ struct objfile *objfile;
+ struct partial_symtab *psymtab;
+ struct symtab *symtab;
+ int lineno;
+ int deleted = 0;
+ struct block **blocks = NULL;
+ int *filter;
+ struct cleanup *old_chain;
-/* Track MAIN */
-static char *name_of_main;
+ ret.nelts = 0;
+ ret.sals = NULL;
-void
-set_main_name (const char *name)
-{
- if (name_of_main != NULL)
+ /* Only expand sals that represent file.c:line. */
+ if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
{
- xfree (name_of_main);
- name_of_main = NULL;
+ ret.sals = xmalloc (sizeof (struct symtab_and_line));
+ ret.sals[0] = sal;
+ ret.nelts = 1;
+ return ret;
}
- if (name != NULL)
+ else
{
- name_of_main = xstrdup (name);
+ struct program_space *pspace;
+ struct linetable_entry *best_item = 0;
+ struct symtab *best_symtab = 0;
+ int exact = 0;
+ char *match_filename;
+
+ lineno = sal.line;
+ match_filename = sal.symtab->filename;
+
+ /* We need to find all symtabs for a file which name
+ is described by sal. We cannot just directly
+ iterate over symtabs, since a symtab might not be
+ yet created. We also cannot iterate over psymtabs,
+ calling PSYMTAB_TO_SYMTAB and working on that symtab,
+ since PSYMTAB_TO_SYMTAB will return NULL for psymtab
+ corresponding to an included file. Therefore, we do
+ first pass over psymtabs, reading in those with
+ the right name. Then, we iterate over symtabs, knowing
+ that all symtabs we're interested in are loaded. */
+
+ old_chain = save_current_program_space ();
+ ALL_PSPACES (pspace)
+ ALL_PSPACE_PSYMTABS (pspace, objfile, psymtab)
+ {
+ if (FILENAME_CMP (match_filename, psymtab->filename) == 0)
+ {
+ set_current_program_space (pspace);
+
+ PSYMTAB_TO_SYMTAB (psymtab);
+ }
+ }
+ do_cleanups (old_chain);
+
+ /* Now search the symtab for exact matches and append them. If
+ none is found, append the best_item and all its exact
+ matches. */
+ symtab_to_fullname (sal.symtab);
+ exact = append_exact_match_to_sals (sal.symtab->filename,
+ sal.symtab->fullname, lineno,
+ &ret, &best_item, &best_symtab);
+ if (!exact && best_item)
+ append_exact_match_to_sals (best_symtab->filename,
+ best_symtab->fullname, best_item->line,
+ &ret, &best_item, &best_symtab);
}
-}
-char *
-main_name (void)
-{
- if (name_of_main != NULL)
- return name_of_main;
- else
- return "main";
+ /* For optimized code, compiler can scatter one source line accross
+ disjoint ranges of PC values, even when no duplicate functions
+ or inline functions are involved. For example, 'for (;;)' inside
+ non-template non-inline non-ctor-or-dtor function can result
+ in two PC ranges. In this case, we don't want to set breakpoint
+ on first PC of each range. To filter such cases, we use containing
+ blocks -- for each PC found above we see if there are other PCs
+ that are in the same block. If yes, the other PCs are filtered out. */
+
+ old_chain = save_current_program_space ();
+ filter = alloca (ret.nelts * sizeof (int));
+ blocks = alloca (ret.nelts * sizeof (struct block *));
+ for (i = 0; i < ret.nelts; ++i)
+ {
+ struct blockvector *bl;
+ struct block *b;
+
+ set_current_program_space (ret.sals[i].pspace);
+
+ filter[i] = 1;
+ blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
+
+ }
+ do_cleanups (old_chain);
+
+ for (i = 0; i < ret.nelts; ++i)
+ if (blocks[i] != NULL)
+ for (j = i+1; j < ret.nelts; ++j)
+ if (blocks[j] == blocks[i])
+ {
+ filter[j] = 0;
+ ++deleted;
+ break;
+ }
+
+ {
+ struct symtab_and_line *final =
+ xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
+
+ for (i = 0, j = 0; i < ret.nelts; ++i)
+ if (filter[i])
+ final[j++] = ret.sals[i];
+
+ ret.nelts -= deleted;
+ xfree (ret.sals);
+ ret.sals = final;
+ }
+
+ return ret;
}
void
_initialize_symtab (void)
{
- add_info ("variables", variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_info ("variables", variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
if (dbx_commands)
- add_com ("whereis", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("whereis", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
add_info ("functions", functions_info,
- "All function names, or those matching REGEXP.");
+ _("All function names, or those matching REGEXP."));
-
/* FIXME: This command has at least the following problems:
1. It prints builtin types (in a very strange and confusing fashion).
2. It doesn't print right, e.g. with
@@ -4017,29 +4880,30 @@ _initialize_symtab (void)
I also think "ptype" or "whatis" is more likely to be useful (but if
there is much disagreement "info types" can be fixed). */
add_info ("types", types_info,
- "All type names, or those matching REGEXP.");
-
-#if 0
- add_info ("methods", methods_info,
- "All method names, or those matching REGEXP::REGEXP.\n\
-If the class qualifier is omitted, it is assumed to be the current scope.\n\
-If the first REGEXP is omitted, then all methods matching the second REGEXP\n\
-are listed.");
-#endif
+ _("All type names, or those matching REGEXP."));
+
add_info ("sources", sources_info,
- "Source files in the program.");
+ _("Source files in the program."));
add_com ("rbreak", class_breakpoint, rbreak_command,
- "Set a breakpoint for all functions matching REGEXP.");
+ _("Set a breakpoint for all functions matching REGEXP."));
if (xdb_commands)
{
- add_com ("lf", class_info, sources_info, "Source files in the program");
- add_com ("lg", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("lf", class_info, sources_info,
+ _("Source files in the program"));
+ add_com ("lg", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
}
- /* Initialize the one built-in type that isn't language dependent... */
- builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
- "", (struct objfile *) NULL);
+ add_setshow_enum_cmd ("multiple-symbols", no_class,
+ multiple_symbols_modes, &multiple_symbols_mode,
+ _("\
+Set the debugger behavior when more than one symbol are possible matches\n\
+in an expression."), _("\
+Show how the debugger handles ambiguities in expressions."), _("\
+Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
+ NULL, NULL, &setlist, &showlist);
+
+ observer_attach_executable_changed (symtab_observer_executable_changed);
}