daily update
[deliverable/binutils-gdb.git] / gdb / symtab.c
index ef70e3ff0d13b4c32379bf8097041d384260f3e8..1a123fb4684ae0cdff18651cd6fcc1e86e892771 100644 (file)
@@ -1,8 +1,8 @@
 /* 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.
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "source.h"
 #include "filenames.h"         /* for FILENAME_CMP */
 
+#include "hashtab.h"
+
 #include "gdb_obstack.h"
+#include "block.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -83,11 +86,20 @@ static struct symbol *lookup_symbol_aux (const char *name,
                                         int *is_a_field_of_this,
                                         struct symtab **symtab);
 
-static struct symbol *lookup_symbol_aux_local (const char *name,
-                                              const char *mangled_name,
-                                              const struct block *block,
-                                              const namespace_enum namespace,
-                                              struct symtab **symtab);
+static
+struct symbol *lookup_symbol_aux_local (const char *name,
+                                       const char *mangled_name,
+                                       const struct block *block,
+                                       const namespace_enum namespace,
+                                       struct symtab **symtab,
+                                       const struct block **static_block);
+
+static
+struct symbol *lookup_symbol_aux_block (const char *name,
+                                       const char *mangled_name,
+                                       const struct block *block,
+                                       const namespace_enum namespace,
+                                       struct symtab **symtab);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -103,6 +115,13 @@ struct symbol *lookup_symbol_aux_psymtabs (int block_index,
                                           const namespace_enum namespace,
                                           struct symtab **symtab);
 
+static
+struct symbol *lookup_symbol_aux_minsyms (const char *name,
+                                         const char *mangled_name,
+                                         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 */
@@ -394,18 +413,11 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol,
 {
   gsymbol->language = language;
   if (gsymbol->language == language_cplus
-      || gsymbol->language == language_java)
+      || gsymbol->language == language_java
+      || gsymbol->language == language_objc)
     {
       gsymbol->language_specific.cplus_specific.demangled_name = NULL;
     }
-  else if (gsymbol->language == language_objc)
-    {
-      gsymbol->language_specific.objc_specific.demangled_name = NULL;
-    }
-  /* OBSOLETE else if (SYMBOL_LANGUAGE (symbol) == language_chill) */
-  /* OBSOLETE   { */
-  /* OBSOLETE     SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */
-  /* OBSOLETE   } */
   else
     {
       memset (&gsymbol->language_specific, 0,
@@ -413,22 +425,35 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol,
     }
 }
 
-/* Initialize a symbol's mangled name.  */
+/* Functions to initialize a symbol's mangled name.  */
+
+/* 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.  */
 
-/* Try to initialize the demangled name for a symbol, based on the
+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_ex
+    (256, htab_hash_string, (int (*) (const void *, const void *)) streq,
+     NULL, objfile->md, xmcalloc, xmfree);
+}
+
+/* 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)
@@ -437,56 +462,117 @@ symbol_init_demangled_name (struct general_symbol_info *gsymbol,
       || 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
+   NAME and LEN.  The hash table corresponding to OBJFILE is used, and the
+   memory comes from that objfile's symbol_obstack.  NAME is copied, so the
+   pointer can be discarded after calling this function.  */
+
+void
+symbol_set_names (struct general_symbol_info *gsymbol,
+                 const char *name, int len, struct objfile *objfile)
+{
+  char **slot;
+  const char *tmpname;
+
+  if (objfile->demangled_names_hash == NULL)
+    create_demangled_names_hash (objfile);
+
+  /* The stabs reader generally provides names that are not NULL-terminated;
+     most of the other readers don't do this, so we can just use the given
+     copy.  */
+  if (name[len] != 0)
+    {
+      char *alloc_name = alloca (len + 1);
+      memcpy (alloc_name, name, len);
+      alloc_name[len] = 0;
+      tmpname = alloc_name;
+    }
+  else
+    tmpname = name;
+
+  slot = (char **) htab_find_slot (objfile->demangled_names_hash, tmpname, INSERT);
+
+  /* If this name is not in the hash table, add it.  */
+  if (*slot == NULL)
+    {
+      char *demangled_name = symbol_find_demangled_name (gsymbol, tmpname);
+      int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+
+      /* If there is a demangled name, place it right after the mangled name.
+        Otherwise, just place a second zero byte after the end of the mangled
+        name.  */
+      *slot = obstack_alloc (&objfile->symbol_obstack,
+                            len + demangled_len + 2);
+      memcpy (*slot, tmpname, len + 1);
+      if (demangled_name)
+       {
+         memcpy (*slot + len + 1, demangled_name, demangled_len + 1);
+         xfree (demangled_name);
+       }
       else
-        {
-          gsymbol->language_specific.cplus_specific.demangled_name = NULL;
-        }
+       (*slot)[len + 1] = 0;
+    }
+
+  gsymbol->name = *slot;
+  if ((*slot)[len + 1])
+    gsymbol->language_specific.cplus_specific.demangled_name
+      = &(*slot)[len + 1];
+  else
+    gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+}
+
+/* Initialize the demangled name of GSYMBOL if possible.  Any required space
+   to store the name is obtained from the specified obstack.  The function
+   symbol_set_names, above, should be used instead where possible for more
+   efficient memory usage.  */
+
+void
+symbol_init_demangled_name (struct general_symbol_info *gsymbol,
+                            struct obstack *obstack)
+{
+  char *mangled = gsymbol->name;
+  char *demangled = NULL;
+
+  demangled = symbol_find_demangled_name (gsymbol, mangled);
+  if (gsymbol->language == language_cplus
+      || gsymbol->language == language_java)
+    {
+      if (demangled)
+       {
+         gsymbol->language_specific.cplus_specific.demangled_name
+           = obsavestring (demangled, strlen (demangled), obstack);
+         xfree (demangled);
+       }
+      else
+       gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+    }
+  else
+    {
+      /* Unknown language; just clean up quietly.  */
+      if (demangled)
+       xfree (demangled);
     }
-#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
 }
 
 /* Return the demangled name for a symbol based on the language for
@@ -495,17 +581,12 @@ char *
 symbol_demangled_name (struct general_symbol_info *gsymbol)
 {
   if (gsymbol->language == language_cplus
-      || gsymbol->language == language_java)
+      || gsymbol->language == language_java
+      || gsymbol->language == language_objc)
     return gsymbol->language_specific.cplus_specific.demangled_name;
 
-  else if (gsymbol->language == language_objc)
-    return gsymbol->language_specific.objc_specific.demangled_name;
-
   else 
     return NULL;
-
-  /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */
-  /* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */
 }
 
 /* Initialize the structure fields to zero values.  */
@@ -727,11 +808,11 @@ 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,
@@ -786,14 +867,13 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
                   int *is_a_field_of_this, struct symtab **symtab)
 {
   struct symbol *sym;
-  struct symtab *s = NULL;
-  struct blockvector *bv;
-  struct minimal_symbol *msymbol;
+  const struct block *static_block;
 
-  /* Search specified block and its superiors.  */
+  /* Search specified block and its superiors.  Don't search
+     STATIC_BLOCK or GLOBAL_BLOCK.  */
 
   sym = lookup_symbol_aux_local (name, mangled_name, block, namespace,
-                                symtab);
+                                symtab, &static_block);
   if (sym != NULL)
     return sym;
 
@@ -859,6 +939,38 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
        }
     }
 
+  /* If there's a static block to search, search it next.  */
+
+  /* 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.  */
+
+  if (static_block != NULL)
+    {
+      sym = lookup_symbol_aux_block (name, mangled_name, static_block,
+                                    namespace, symtab);
+      if (sym != NULL)
+       return sym;
+    }
+
   /* 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
@@ -875,65 +987,12 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
      a mangled variable that is stored in one of the minimal symbol tables.
      Eventually, all global symbols might be resolved in this way.  */
 
-  if (namespace == VAR_NAMESPACE)
-    {
-      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);
-
-              /* This call used to pass `SYMBOL_NAME (msymbol)' as the
-                 `name' argument to lookup_block_symbol.  But the name
-                 of a minimal symbol is always mangled, so that seems
-                 to be clearly the wrong thing to pass as the
-                 unmangled name.  */
-             sym = lookup_block_symbol (block, name, 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, name,
-                                             mangled_name, namespace);
-               }
-
-             /* 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_".
-
-                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:");
-              */
-
-             if (symtab != NULL)
-               *symtab = s;
-             return fixup_symbol_section (sym, s->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, NULL,
-                                       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. */
-       }
-    }
+  sym = lookup_symbol_aux_minsyms (name, mangled_name,
+                                  namespace, is_a_field_of_this,
+                                  symtab);
+  
+  if (sym != NULL)
+    return sym;
 
 #endif
 
@@ -975,87 +1034,13 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
      the static check in this case? 
    */
 
-  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);
-              /* This call used to pass `SYMBOL_NAME (msymbol)' as the
-                 `name' argument to lookup_block_symbol.  But the name
-                 of a minimal symbol is always mangled, so that seems
-                 to be clearly the wrong thing to pass as the
-                 unmangled name.  */
-             sym = lookup_block_symbol (block, name, 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, name,
-                                             mangled_name, namespace);
-               }
-             /* If we found one, return it */
-             if (sym)
-               {
-                 if (symtab != NULL)
-                   *symtab = s;
-                 return sym;
-               }
 
-             /* 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:");
-              */
-           }
-
-         /* 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,
-                                       NULL, namespace, is_a_field_of_this,
-                                       symtab);
-           }
-       }
-    }
+  sym = lookup_symbol_aux_minsyms (name, mangled_name,
+                                  namespace, is_a_field_of_this,
+                                  symtab);
+  
+  if (sym != NULL)
+    return sym;
 
 #endif
 
@@ -1064,11 +1049,47 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
   return NULL;
 }
 
-/* Check to see if the symbol is defined in BLOCK or its
-   superiors.  */
+/* Check to see if the symbol is defined in BLOCK or its superiors.
+   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  If we don't find a
+   match, store the address of STATIC_BLOCK in static_block.  */
 
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *mangled_name,
+                        const struct block *block,
+                        const namespace_enum namespace,
+                        struct symtab **symtab,
+                        const struct block **static_block)
+{
+  struct symbol *sym;
+  
+  /* Check if either no block is specified or it's a global block.  */
+
+  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
+    {
+      *static_block = NULL;
+      return NULL;
+    }
+
+  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
+    {
+      sym = lookup_symbol_aux_block (name, mangled_name, block, namespace,
+                                    symtab);
+      if (sym != NULL)
+       return sym;
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  /* We've reached the static block.  */
+
+  *static_block = block;
+  return NULL;
+}
+
+/* Look up a symbol in a block; if found, locate its symtab, fixup the
+   symbol, and set block_found appropriately.  */
+
+static struct symbol *
+lookup_symbol_aux_block (const char *name, const char *mangled_name,
                         const struct block *block,
                         const namespace_enum namespace,
                         struct symtab **symtab)
@@ -1078,32 +1099,28 @@ lookup_symbol_aux_local (const char *name, const char *mangled_name,
   struct blockvector *bv;
   struct block *b;
   struct symtab *s = NULL;
-  
-  while (block != 0)
+
+  sym = lookup_block_symbol (block, name, mangled_name, namespace);
+  if (sym)
     {
-      sym = lookup_block_symbol (block, name, mangled_name, namespace);
-      if (sym)
+      block_found = block;
+      if (symtab != NULL)
        {
-         block_found = block;
-         if (symtab != NULL)
+         /* Search the list of symtabs for one which contains the
+            address of the start of this block.  */
+         ALL_SYMTABS (objfile, s)
            {
-             /* 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;
+             bv = BLOCKVECTOR (s);
+             b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+             if (BLOCK_START (b) <= BLOCK_START (block)
+                 && BLOCK_END (b) > BLOCK_START (block))
+               goto found;
            }
-
-         return fixup_symbol_section (sym, objfile);
+       found:
+         *symtab = s;
        }
-      block = BLOCK_SUPERBLOCK (block);
+      
+      return fixup_symbol_section (sym, objfile);
     }
 
   return NULL;
@@ -1202,6 +1219,135 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
   return NULL;
 }
 
+/* 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.  */
+
+/* NOTE: carlton/2002-12-05: At one point, this function was part of
+   lookup_symbol_aux, and what are now 'return' statements within
+   lookup_symbol_aux_minsyms returned from lookup_symbol_aux, even if
+   sym was NULL.  As far as I can tell, this was basically accidental;
+   it didn't happen every time that msymbol was non-NULL, but only if
+   some additional conditions held as well, and it caused problems
+   with HP-generated symbol tables.  */
+
+static struct symbol *
+lookup_symbol_aux_minsyms (const char *name,
+                          const char *mangled_name,
+                          const namespace_enum namespace,
+                          int *is_a_field_of_this,
+                          struct symtab **symtab)
+{
+  struct symbol *sym;
+  struct blockvector *bv;
+  const struct block *block;
+  struct minimal_symbol *msymbol;
+  struct symtab *s;
+
+  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_sect_symtab()
+            has a side-effect of doing psymtab-to-symtab expansion,
+            for the found symtab.  */
+         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);
+
+             /* This call used to pass `SYMBOL_NAME (msymbol)' as the
+                `name' argument to lookup_block_symbol.  But the name
+                of a minimal symbol is always mangled, so that seems
+                to be clearly the wrong thing to pass as the
+                unmangled name.  */
+             sym =
+               lookup_block_symbol (block, name, 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, name,
+                                            mangled_name, namespace);
+               }
+
+             /* NOTE: carlton/2002-12-04: The following comment was
+                taken from a time when two versions of this function
+                were part of the body of lookup_symbol_aux: this
+                comment was taken from the version of the function
+                that was #ifdef HPUXHPPA, and the comment was right
+                before the 'return NULL' part of lookup_symbol_aux.
+                (Hence the "Fall through and return 0" comment.)
+                Elena did some digging into the situation for
+                Fortran, and she reports:
+
+                "I asked around (thanks to Jeff Knaggs), and I think
+                the story for Fortran goes like this:
+
+                "Apparently, in older Fortrans, '_' was not part of
+                the user namespace.  g77 attached a final '_' to
+                procedure names as the exported symbols for linkage
+                (foo_) , but the symbols went in the debug info just
+                like 'foo'. The rationale behind this is not
+                completely clear, and maybe it was done to other
+                symbols as well, not just procedures."  */
+
+             /* 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:");
+              */
+
+             if (symtab != NULL && sym != NULL)
+               *symtab = s;
+             return fixup_symbol_section (sym, s->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,
+                                       NULL, namespace, is_a_field_of_this,
+                                       symtab);
+           }
+       }
+    }
+
+  return NULL;
+}
+
 /* Look, in partial_symtab PST, for symbol NAME.  Check the global
    symbols if GLOBAL, the static symbols if not */
 
@@ -1211,7 +1357,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
 {
   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;
   
@@ -1234,6 +1380,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
 
       bottom = start;
       top = start + length - 1;
+      real_top = top;
       while (top > bottom)
        {
          center = bottom + (top - bottom) / 2;
@@ -1244,7 +1391,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
            {
              do_linear_search = 1;
            }
-         if (strcmp (SYMBOL_SOURCE_NAME (*center), name) >= 0)
+         if (strcmp (SYMBOL_PRINT_NAME (*center), name) >= 0)
            {
              top = center;
            }
@@ -1259,7 +1406,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
       /* 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 && SYMBOL_MATCHES_NAME (*top,name))
        {
          if (SYMBOL_NAMESPACE (*top) == namespace)
            {
@@ -1490,15 +1637,15 @@ lookup_block_symbol (register const struct block *block, const char *name,
            {
              do_linear_search = 1;
            }
-         if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
+         if (SYMBOL_PRINT_NAME (sym)[0] < name[0])
            {
              bot = inc;
            }
-         else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+         else if (SYMBOL_PRINT_NAME (sym)[0] > name[0])
            {
              top = inc;
            }
-         else if (strcmp (SYMBOL_SOURCE_NAME (sym), name) < 0)
+         else if (strcmp (SYMBOL_PRINT_NAME (sym), name) < 0)
            {
              bot = inc;
            }
@@ -1530,7 +1677,7 @@ lookup_block_symbol (register const struct block *block, const char *name,
            {
              return sym;
            }
-          if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
+          if (SYMBOL_PRINT_NAME (sym)[0] > name[0])
             {
               break;
             }
@@ -1592,7 +1739,8 @@ lookup_block_symbol (register const struct block *block, const char *name,
                  SYMBOL_CLASS (sym) != LOC_REF_ARG &&
                  SYMBOL_CLASS (sym) != LOC_REGPARM &&
                  SYMBOL_CLASS (sym) != LOC_REGPARM_ADDR &&
-                 SYMBOL_CLASS (sym) != LOC_BASEREG_ARG)
+                 SYMBOL_CLASS (sym) != LOC_BASEREG_ARG &&
+                 SYMBOL_CLASS (sym) != LOC_COMPUTED_ARG)
                {
                  break;
                }
@@ -1635,18 +1783,6 @@ find_active_alias (struct symbol *sym, CORE_ADDR addr)
 }
 \f
 
-/* 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. */
 
@@ -1957,9 +2093,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;
@@ -2595,8 +2733,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
@@ -2814,6 +2952,12 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
              {
                if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (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_NAMESPACE
                        || lookup_symbol (SYMBOL_NAME (msymbol),
                                          (struct block *) NULL,
@@ -2965,7 +3109,7 @@ print_symbol_info (namespace_enum kind, struct symtab *s, struct symbol *sym,
     {
       type_print (SYMBOL_TYPE (sym),
                  (SYMBOL_CLASS (sym) == LOC_TYPEDEF
-                  ? "" : SYMBOL_SOURCE_NAME (sym)),
+                  ? "" : SYMBOL_PRINT_NAME (sym)),
                  gdb_stdout, 0);
 
       printf_filtered (";\n");
@@ -2988,7 +3132,7 @@ print_msymbol_info (struct minimal_symbol *msymbol)
     tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
                                   "016l");
   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
@@ -3103,7 +3247,7 @@ rbreak_command (char *regexp, int from_tty)
        {
          break_command (SYMBOL_NAME (p->msymbol), from_tty);
          printf_filtered ("<function, no debug info> %s;\n",
-                          SYMBOL_SOURCE_NAME (p->msymbol));
+                          SYMBOL_PRINT_NAME (p->msymbol));
        }
     }
 
@@ -3111,19 +3255,6 @@ rbreak_command (char *regexp, int from_tty)
 }
 \f
 
-/* 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);
-}
-\f
-
 /* Helper routine for make_symbol_completion_list.  */
 
 static int return_val_size;
This page took 0.036462 seconds and 4 git commands to generate.